Will
Will

Reputation: 544

Parse.com Query containedIn Array of Pointers

Original Question

I'm trying to query all instances where the ID inside of allFriends matches the ID of Creator. allFriends is an array of IDs from an earlier query. What is the proper syntax for containedIn with an array of pointers.

allFriends:

["1EGomEr0Tk", "iMJbVrPfGG", "DVOwabZkaQ", "zhvd8mAdhl"]

Code:

query.containedIn("Creator", {
                __type: "Pointer",
                className: "User",
                objectId: allFriends
            })

Error:

code: 102
error: "$in requires an array"

Update #1

I've found that I need to convert the allFriends array of IDs into a pointer map. However _.map is being computed as undefined.

Code:

var pointers = _.map(allFriends, function(item_id) {
            var pointer = new Parse.Object("allFriends");
            pointer.id = item_id;
            return pointer;
            });
            query.containedIn("Creator", pointers);

Error:

Uncaught ReferenceError: map is not defined

Upvotes: 4

Views: 5763

Answers (4)

If you want to have multiple-pointer column, just create array column and fill it with _User objects. Result will look like this and it will really be array of pointers:

[{"__type":"Pointer","className":"_User","objectId":"kIg9Kzzls9"},
{"__type":"Pointer","className":"_User","objectId":"TGCBZm52zW"},
{"__type":"Pointer","className":"_User","objectId":"YfGT9GvJs6"}]

Using include to get full objects in query also works, it is an array of pointers.

Upvotes: 1

Jeremy Piednoel
Jeremy Piednoel

Reputation: 406

It might be a little late but you can also use the method createWithoutData to build objects from IDs

Documentation

Upvotes: 1

Timothy Walters
Timothy Walters

Reputation: 16874

If your "Creator" column is of type Pointer<_User> and your allFriends array is an array of IDs for Users, then this is what you need to do:

Create an array of Pointer<_User> objects from allFriends:

var pointers = _.map(allFriends, function(friendId) {
  var pointer = new Parse.User();
  pointer.id = friendId;
  return pointer;
});

Once you have an array of Pointer<_User> you can then compare your column:

query.containedIn('Creator', pointers);

You were very close, it was just a matter of creating the right kind of pointers.

Upvotes: 11

danh
danh

Reputation: 62676

Parse lets you define a pointer column or an array column. Arrays are an ordered collection of scalar types (numbers, strings, etc) or they can be an array of pointers.

Pointers

When getting and setting a pointer, the operand is a PFObject. In other words, for the setter:

myObject.set("somePointerCol", someOtherObject);

where someOtherObject is a PFObject, possibly an empty one, with only an ID defined (as you indicated correctly in your edit). For the getter:

myQuery.first().then(function(myObject) {
    var someOtherObject = myObject.get("somePointerCol");
});

someOtherObject will be an empty PFObject with just its objectId set. If you want the referred-to object fetched as well, then qualify your query like this:

myQuery.include("somePointerCol");
// someOtherPointerCol on the retrieved object will contain a complete, fetched object

Arrays and Arrays of Pointers

PFObject provides a couple methods for arrays, you can add to an array with add and addUnique, and remove from it with remove. The elegant part is that these methods can be just as readily applied when the array is an array of pointers.

myObject.addUnique("arrayOfPointersCol", someOtherObject);
// or...
myObject.remove("arrayOfPointersCol", someOtherObject);

Finally, PFQuery deals with arrays fairly transparently. To find any myObject who's arrayOfPointersCol contains a PFObject, use equalTo, as if its just a single value.

myQuery.equalTo("arrayOfPointersCol", someOtherObject);

// if you have only an id, say someId, then
var SomeOtherClass = Parse.Object.extend("SomeOtherClass");
var someOtherObject = new SomeOtherClass();
someOtherObject.id = someId;

myQuery.equalTo("arrayOfPointersCol", someOtherObject);

Similarly to non-array pointers, you can eagerly fetch all of the elements in that array:

myQuery.include("arrayOfPointersCol");  // but be careful, keep array lengths short

Underscore

Last, and unrelated to the array or pointer ideas, you certainly can map an array of object ids, transforming them into an array of pointer objects. The code you posted looks fine, but it depends on the underscore library -- which is a very useful library that provides the _.map function among many others.

Upvotes: 5

Related Questions