Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How exactly does the fetchAllIfNeeded differ from fetchAll in the JS SDK?

I never quite understood the if needed part of the description.

.fetchAll() Fetches the given list of Parse.Object.

.fetchAllIfNeeded() Fetches the given list of Parse.Object if needed.

What is the situation where I might use this and what exactly determines the need? I feel like it's something super elementary but I haven't been able to find a satisfactory and clear definition.

In the example in the API, I notice that the fetchAllIfNeeded() has:

// Objects were fetched and updated.

In the success while the fetchAll only has:

// All the objects were fetched.

So does the fetchAllIfNeeded() also save stuff too? Very confused here.

UPDATES

TEST 1

Going on some of the hints @danh left in the comments I tried the following things.

var todos = [];
var x = new Todo({content:'Test A'});  // Parse.Object
todos.push(x);
x.save();

// So now we have a todo saved to parse and x has an id. Async assumed.

x.set({content:'Test B'});

Parse.Object.fetchAllIfNeeded(todos);

So in this scenario, my client x is different than the server. But the x.hasChanged() is false since we used the set function and the change event is triggered. fetchAllIfNeeded returns no results. So it isn't that it's trying to compare this outright to what is on the server to sync and fetch.

I notice that in the request payload, running the fetchAllIfNeeded is sending the following interesting thing.

{where: {objectId: {$in: []}}, _method: "GET",…}

So it seems that on the clientside something determines whether an object isNeeded

Test 2

So now, based on the comments I tried manipulating the changed state of the object by setting with silent.

x.set({content:'Test C'}, {silent:true});
x.hasChanged(); // true
Parse.Object.fetchAllIfNeeded(todos);

Still nothing interesting. Clearly the server state ("Test A") is different than clientside ("Test C"). and I still results [] and the request payload is:

{where: {objectId: {$in: []}}, _method: "GET",…}

UPDATE 2

Figured it out by looking at the Parse source. See answer.

like image 797
jmk2142 Avatar asked Apr 16 '15 00:04

jmk2142


People also ask

What is Javascript ParseObject?

Parse~ ParseObject Creates a new model with defined attributes. You won't normally call this method directly. It is recommended that you use a subclass of Parse. Object instead, created by calling extend .

What is Parse user?

A Parse. User object is a local representation of a user persisted to the Parse cloud. This class is a subclass of a Parse. Object, and retains the same functionality of a Parse. Object, but also extends it with various user specific methods, like authentication, signing up, and validation of uniqueness.


1 Answers

After many manipulations, then taking a look at the source - I figured this out. Basically fetchAllIfNeeded will fetch models in an array that have no data, meaning there are no attribute properties and values.

So the use case would be you have lets say a parent object with an array of nested Parse Objects. When you fetch the parent object, the nested child objects in the array will not be included (unless you have the include query constraint set). Instead, the pointers are sent back to clientside and in your client, those pointers are translated into 'empty' models with no data, basically just blank Parse.Objects with ids.

Specifically, the Parse.Object has an internal Boolean property called _hasData which seems to be toggled true any time stuff like set, or fetch, or whatever gives that model attributes.

So, lets say you need to fetch those child objects. You can just do something like

var childObjects = parent.get('children'); // Array
Parse.Object.fetchAllIfNeeded(childObjects);

And it will search for those children who are currently only represented as empty Objects with id.

It's useful as opposed to fetchAll in that you might go through the children array and lazily load one at a time as needed, then at a later time need to "get the rest". fetchAllIfNeeded essentially just filters "the rest" and sends a whereIn query that limits fetching to those child objects that have no data.

In the Parse documentation, they have a comment in the callback response to fetchAllIfNeeded as:

// Objects were fetched and UPDATED.

I think they mean the clientside objects were updated. fetchAllIfNeeded is definitely sending GET calls so I doubt anything updates on the serverside. So this isn't some sync function. This really confused me as I instantly thought of serverside updating when they really mean:

// Client objects were fetched and updated.
like image 65
jmk2142 Avatar answered Oct 22 '22 08:10

jmk2142