Ember.js - Function finished before store is done - ember.js

I'm building an ember app, and I keep running into the same problem where I make a call to the store, but the function keeps compiling before the store has retrieved the data from the backend. Specifically I'm having the problem with a findRecord. I've implemented it both ways:
var admin = this.store.findRecord('admin', 1);
console.log(admin.get('season'));
console.log('Are we here?');
and
this.store.findRecord('admin', 1).then(function(admin) {
console.log(admin.get('season'));
});
console.log('Are we here?');
In both cases, the Are we here? is logged BEFORE the season. Obviously the console logs are just for the example, and it creates an actual problem with what I'm trying to get done. Does anybody know a simple fix for this delay?
Thanks.

Of course it is. It's an asynchronous behavior. It takes some time to solve promise which is returned from findRecord(), thus the consequence is:
this.store.findRecord(); //synchronous
console.log('we are here'); //synchronous
in the meantime a promise returned from findRecord() gets resolved (asynchronous behavior)
console.log(admin.get('season'));

An asynchronous call will not stop your code from progressing, that´s the purpose of it. Else it would block UI updates and user interaction while loading data.

Related

ember-data 2.0 and Offline

I am creating a new ember app. I want to use the newest version of ember-data. (ember-data 2.0). I want it to be a mobile webapp. Therefore it must handle variable network access and even offline.
I want it to store all data locally and use that data when it goes offline so the user gets the same experience regardless of the network connectivity.
Is ember-data 2.0 capable of handling the offline case? Do I just make an adapter that detects offline/online and then do....?
Or do I have to make my own in-between layer to hide the offline handling from ember-data?
Are there any libraries out there that has this problem solved? I have found some, but are there any that is up to date with the latest version of ember-data?
If device will go offline and user will try to transition to route, for which model is not loaded yet, you will have an error. You need to handle these situations yourself. For example, you may create a nice page with error message and a refresh button. To do this, you need:
First, In application route, create error action (it will catch errors during model hook), and when error occurs, save transition in memory. Do not try to use local storage for this task, it will save only properties, while we need an actual transition object. Use either window.failedTransition or inject in controllers and routes a simple object, which will contain a failed transition.
actions: {
error: function (error, transition) {
transition.abort();
/**
* You need to correct this line, as you don't have memoryStorage
* injected. Use window.failedTransition, or create a simple
* storage, Iy's up to you.
*/
this.get('memoryStorage').set('failedTransition', transition);
return true; //This line is important, or the whole idea will not work
}
}
Second, Create an error controller and template. In error controller define an action, retry:
actions: {
retry: function () {
/**
* Correct this line too
*/
var transition = this.get('memoryStorage').getAndRemove('failedTransition');
if (transition !== undefined) {
transition.retry();
}
}
}
Finally, In error template display a status and an error text (if any available) and a button with that action to retry a transition.
This is a simple solution for simple case (device gone offline just for few seconds), maybe you will need something way more complex. If you want your application to fully work without a network access, than you may want to use local storage (there is an addon https://github.com/funkensturm/ember-local-storage) for all data and sync it with server from time to time (i.e sync data every 10 sec in background). Unfortunately I didn't try such things, but I think it is possible.

Loopback: return error from beforeValidation hook

I need to make custom validation of instance before saving it to MySQL DB.
So I perform (async) check inside beforeValidate model hook.
MyModel.beforeValidate = function(next){
// async check that finally calls next() or next(new Error('fail'))
}
But when check fails and I pass Error obj to next function, the execution continues anyway.
Is there any way to stop execution and response to client with error?
This is a known bug in the framework, see https://github.com/strongloop/loopback/issues/614
I am working on a new hook implementation that will not have issues like the one you have experienced, see loopback-datasource-juggler#367 and the pull request loopback-datasource-juggler#403

Getting "Error: Assertion Failed: calling set on destroyed object" when trying to rollback a deletion

I am looking into how to show proper deletion error message in ember when there is an error coming back from the server. I looked at this topic and followed its suggestion:
Ember Data delete fails, how to rollback
My code is just like it, I return a 400 and my catch fires and logs, but nothing happens, when I pause it in the debugger though and try to rollback, I get Error: Assertion Failed: calling set on destroyed object
So A) I cannot rollback B) the error is eaten normally.
Here is my code
visitor.destroyRecord().then(function() {
console.log('SUCCESS');
}).catch(function(response) {
console.log('failed to remove', response);
visitor.rollback();
});
In case it's relevant, my model does have multiple relationships. What am I doing wrong? Ember-data version is 1.0.0.8 beta (previous one from the release a few days ago).
Thanks in advance.
EDIT
I discovered now that the record actually is restored currently inside the cache according to ember inspector, but the object will not reappear in the rendering of the visitors. I need some way to force it to reload into the template...
After destroyRecord, the record is gone and the deletion cannot be rolled back. The catch clause will just catch a server error. If you want the record back, and think it's still on the server, you'll have to reload it.
See the following comment on deleteRecord from the Ember Data source:
Marks the record as deleted but does not save it. You must call
`save` afterwards if you want to persist it. You might use this
method if you want to allow the user to still `rollback()` a
delete after it was made.
This implies that a rollback after save is not possible. There is also no sign anywhere I can see in the Ember Data code for somehow reverting a record deletion when the DELETE request fails.
In theory you might be able to muck with the isDeleted flag, or override various internal hooks, but I'd recommend against that unless you really know how things work.
Try reloading the model after the rollback. It will reload from the server but it was the only way around this that I could find.
visitor.destroyRecord().then(function() {
console.log('SUCCESS');
}).catch(function(response) {
console.log('failed to remove', response);
visitor.rollback();
visitor.reload().then(function(vis)
{
console.log('visitor.reload :: ' + JSON.stringify(vis));
});
});
Hope that helps.

Hitting refresh button after call to createRecord causes EmberData to send erroneous GET message

I posted this on the Ember-Data issues list:
https://github.com/emberjs/data/issues/1796
I read some posting saying that an 'id' should not be specified during call to createRecord. I tried this and noticed the following: if an 'id' is not specified, hitting the refresh button will cause Ember Data to send a GET request to the server requesting a record with a 'null' id, so it doesn't solve the problem.
Does anyone have a suggestion on a workaround for this?
I've also posted a somewhat related problem here (rogue GET message):
https://github.com/emberjs/data/issues/1794
That's not really a bug, you're just note really programming asynchronously. You have your transitionTo call before the record is done being created. So you're routing to a page that does not yet exist. While Ember.js might have some fancy features to make that not an issue, it can't handle every scenario. What you should be doing it routing after the record is created. Since createRecord returns a record and not a promise, I suggest using the didCreate hook.
var newRec = this.store.createRecord('scenario', temp);
newRecord.one('didCreate', function() {
Em.run.next(function() {
this.transitionToRoute ('scenarios.scenario', newRec);
}.bind(this));
}.bind(this));
You can see another similar example here.

Facebook JavaScript API: run a line of code once asynch calls are completed

I have a piece of code which makes multiple nested calls to FB.api to retrieve certain information. Eventually, it creates an object called "myfriends" and stores my desired information in that object.
What I want to do is to use that object, after it is filled in with data (i.e. after all asynch calls are done), to run something else. In other words, I need a way for my code to know that those calls are complete. How can I do that?
call 'myfriends' after async request has completed.
Example:
FB.api('/me', function(response) {
alert('Your name is ' + response.name);
// Use 'myfriends' object here
});
I ended up using callback functions. The other problem I had was that my inner API call was in a loop; I ended up using an asynchronous looping function. This combination solved my problem.