This lesson is for PRO members.

Unlock this lesson NOW!
Already subscribed? sign in

Querying an Immutable.js Map()

4:47 JavaScript lesson by

Learn how to query an Immutable.Map() using get, getIn, has, includes, find, first and last. These are powerful operators that make finding data in an object graph pain free.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

Learn how to query an Immutable.Map() using get, getIn, has, includes, find, first and last. These are powerful operators that make finding data in an object graph pain free.

Avatar
awv-inf

The official immutable.js docs are impossible to read, that is why people come here.

But instead of learning how these functions work we're covering wrappers, abstractions and tests.

I really wish you would have just used the functions as they are, show what they return, thereby cutting the lessons time in half. Right now i am not sure if i better crawl through robotic typescript definitions than watch yet another test that calls this and that wrapper named differently than the immutable method way outside the view comparing results not shown.

Avatar
J.S.

Hi @awv-inf. Thanks for the feedback. Some love the TDD approach and others have expressed your same concern. Will definitely try to find a happy medium in the future!

In reply to awv-inf
Avatar
Kostiantyn

I suppose you have the typo in the case "should find nested keys":

var todos = Immutable.Map();
    var todos2 = Immutable.Map();

    _.each(_.range(10), (index) => {
      todos = ....
    });

    _.each(_.range(10), (index) => {
      todos = ...
    });

The second one for _.each should be todos2... Am I right? Because if we check console.log(todos.size) right after the _.each... the result will be 1...

I such case we can goo deeper and verify it:

const todo2ID = todos2.last().id;
expect(multipleTodoStates.getIn(["todo2", todo2ID], null)).to.equal(todos2.last());

You can query an unordered Immutable Map with a few useful methods, get, has, includes, first, last, getIn, and way down here we have another one called find. Let's get to writing some tests.

Here I've got the to-do class, which will compose our application. I've also got the add to-do method, which is a convenience method that will help us later. I've also added this find to-do method, and we'll get to that in a minute.

First things first. Let's go ahead and just get an item on the to-do. I've already set up a to-do. I've instantiated an Immutable Map, and I've added the to-do to it. We're going to write an expect that will just get the to-do's ID.

Here's the expect, here's the Immutable Map, and here's the to-do ID. Now, this should return the to-do itself, so there's should be two equal to-do. We've got a passing test.

We also have a has operator. Say we don't want to return the actual todo, we just want to know if it's in there. Let's go ahead and try that. Let's do has todo.id. Now, the test failed, because it does not return the actual to-do, but it does return a boolean, so this should equal true, and now we have a passing test.

We also should check to see if we'll return something that's not inside of there. Let's just say unknown key. Unknown key. That, as expected, does not pass. We'll say that's false.

That's get and has. Now, if we want to look up something not by ID, but by the object itself, we can use the includes operator.

Here's the same setup. It should properly report included values. We'll write an expectation that uses the include method and passes in the todo object. Now, we should see that this is equal to true, because it's inside there.

Finding nested data can be a little bit trickier. Let's go ahead and build out another map that contains both these todo Immutable Maps, and see if we can't find an ID inside of one of those.

Let's go ahead and create some state. Here's a multiple to-do states object that is a map, and it has two keys of todo1 and todo2, and we're going to pass in our Immutable Map to both of those. This is a nested Immutable Map.

Now, let's store an ID that we want to search for inside of this Immutable Map. We'll say const todo ID = todos.first.ID. OK? Here's that first operator that I was showing you earlier.

I won't be covering this too much right now. But keep in mind that this returns the first one and the last one refers the last one.

Now, we can write an expectation on multiple todo states and use the getIn operator. The getIn operator takes an array, OK, and then it takes an array that defines a path. The first path, the first key we want to look for is todo1. Within todo1 we want to find that ID. OK? That's how getIn works.

It also accepts a default value if it can't find anything, and we'll put null there for now, so we know that it's not working if we see null coming back. Then we'll see if that's equal to the first todo that we set. Sure enough, it is, it's equal to the first to-do that we had looked for. That's how you use getIn.

Now, we also have a way to find something that's not sort of standard. We can actually write a function that will go and search in the Immutable Map for something that may be more difficult to find.

I've written a find to-do method that uses the find operator on the Immutable Map, which accepts a function which will then scan through all of the items inside of the map, and whichever one you want to return, you just return true. In this instance, we're going to see if the ID that we pass in is equal to the ID that we want, and we will return that value back.

Let's go ahead and write an expectation to see how that works. Now, we've got two todos added to this map here. We'll see expect, find, todo, todos, and we'll say, the first todo up top, we'll say, can we find that todo inside of the todos. We'll see if that's equal to it.

Sure enough, it looped through all of them, found the ID, and returned the first todo that we found. That's how you query.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?