I'm listing a hasMany relationship, of which a record can be updated, deleted or added.
I want to provide the user with a revert option, which should revert the list to its last saved state.
For deletion, I do item.deleteRecord(), so that I can revert the changes using rollbackAttributes(). Changes are reverted as expected, but it behaves inconsistently while saving (saving the model to which the items belong doesn't update its dirty state on first save, next record disappears from the view though the changes sent to the back-end properly, and so on).
So I decided to use unloadRecord, but once a record is unloaded, I'm unable to revert it without reloading the page.
One way would be to save the old state and use it on revert. Please help me with a cleaner to achieve this.
For an idea of my model, Ember: Model's property changes not detected in computed property
Unloading a record removes it from Ember Data’s in-memory data store.
The only way to get that record back, is by re-requesting it from the server, aka: this.store.findRecord().
You’ll get a fresh copy from the server, but that won’t have any changes the client made before it was unloaded, and may have new changes from other clients.
Related
I have read Ember docs related to Substates etc and I understand how it works. In my current application my loading.hbs and other child loading.hbs templates work fine.
I just want to discuss a use case.
In my route A, in my model function I do fetchAll for my model.
I go to Route A, First time api request is sent and I see my loading screen.
now I navigate to some other route B.
now I come back to first route A, api request is sent again but this
time loading screen is not shown.
I want to develop my understanding here. Now the second time loading screen is not shown which tells us that store had data so there is no sense to put it on loading and after fetch store sent request to sync with backend.
QUESTION
Now I want to know if this is a default behaviour of Ember with Ember-data?
To show this loading screen, will I have to do something manually?
Ideally what I want is, if on second request data was fetched then show it and at the same time show loader to tell user that it is syncing with backend as well.
I know everything can be done manually, I don't want to reinvent the wheel or do things in non-conventional way. So I want to know best optimized solution for this as provided by Ember which an experienced Ember developer can help me understand.
Thanks in advance.
Now I want to know if this is a default behaviour of Ember with
Ember-data?
Yes, that's the default behavior of Ember data when you do a findRecord or findAll where shouldBackgroundReloadRecord or shouldBackgroundReloadAll event of the adapter respectively, is defaulted to true. You can turn this off by returning false and ensuring shouldReloadAll or shouldReloadRecord respectively are set at true to ensure the request always hits the API and not fetches from cache.
Ideally, showing data immediately on the screen is always advisable as it has a better UX in terms of giving the user a feel that data is already there and that some parts of the data is being fetched. Check here
To show this loading screen, will I have to do something manually?
You may also want to read this
To add further details after my own research, I found helpful and relevant details in Ember docs.This is all about caching.
If records were already there then promise will be resolved immediately that's why I don't see loading screen for already loaded record, at the same time Ember-Data syncs with backend as well and re-render the template.
Ember Model Docs
Caching
The store will automatically cache records for you. If a record had already been loaded, asking for it a second time will always return the same object instance. This minimizes the number of round-trips to the server, and allows your application to render its UI to the user as fast as possible.
For example, the first time your application asks the store for a person record with an ID of 1, it will fetch that information from your server.
However, the next time your app asks for a person with ID 1, the store will notice that it had already retrieved and cached that information from the server. Instead of sending another request for the same information, it will give your application the same record it had provided it the first time. This feature—always returning the same record object, no matter how many times you look it up—is sometimes called an identity map.
Using an identity map is important because it ensures that changes you make in one part of your UI are propagated to other parts of the UI. It also means that you don't have to manually keep records in sync—you can ask for a record by ID and not have to worry about whether other parts of your application have already asked for and loaded it.
One downside to returning a cached record is you may find the state of the data has changed since it was first loaded into the store's identity map. In order to prevent this stale data from being a problem for long, Ember Data will automatically make a request in the background each time a cached record is returned from the store. When the new data comes in, the record is updated, and if there have been changes to the record since the initial render, the template is re-rendered with the new information.
I have a new team member, which belongs in a team but the member doesn’t have an ID yet because the record hasn't been send to the server yet how do I tell the team that the member belongs in the team and let it appear in the team list before sending the team member to the server and assigning a unique ID to the member.
I think ember is geared towards saving the record to the back end, and then on the success callback creating your relationship and save it again. This ensures that ember-data remains a slave to the backend, ensuring data integrity.
You could look at creating an ID in ember, but this certainly sounds like here be dragons as you would need to purge your ember-data store and and get the real records and ID's from the server.
This process could be simplified by placing a flag on your model to say that it has a generated ID, but as I said here be dragons.
The safest option is to either just establish relationships once a record has been saved to the back end, or if offline is a real concern, you could use something like Ember Pouch to keep a synced local copy of your datastore, this will make the whole issue of resolving ID's a little more consistent.
Finally you could look into some sort of localStorage man in the middle to sync with your db, it has been discussed in this SO question.
I'm working on a lightweight app, and I have quite a few situations where the user submits a form, the form data is processed and pushed to the datastore, and then the user is redirected to a page that displays some of the same data. It's quite often the case that the user gets to the page before the datastore has been updated, so they see old data. Is there any way to have the app wait for the datastore to update before proceeding? The obvious hacky solution is calling sleep(1), but that's obviously not ideal and takes longer than the actual update.
Just get the key the .put() returns:
key = mything.put()
and pass it on to the other page (e.g via urlsafe). The other page can rebuild the key and then
thething = key.get()
will always give you updated data -- i.e, this (key.get()) is one simple way to get strong consistency from the GAE datastore!
I have a real time emberjs app. I'm trying to implement a real time notification system, where any updates on one client will be propagated over all the other clients. Hence all the changes happen in real time over all the browsers.
I have Labels extending DS.Model objects. Every time one client creates a new record, the other clients run App.Label.find() which updates the record array correctly. Now the problem is when a client deletes a record and commits the store, App.Label.find() will no remove the record on the other clients. So my question is:
Is there a way you can update your local records from a persistent layer, which will remove all the deleted records?
I got it done by checking for .isDeleted
{{unless "model.isDeleted"}}
show only not deleted models
{{/unless}}
I'm developing a push application and need to remove items from a DS.Store without invoking any actions. I'm able to insert objects using load(), but need to be able to "unload" an object after it has been deleted on another client.
Thanks
record.unloadRecord();
This clears belongsTo and hasMany relationships on the record and then transitions the record to the deleted.saved state, all without sending anything to the server.
Rather than remove a record from the store I just need to change the record state.
record.get('stateManager').goToState('deleted.saved');
For ember-data V ~1.0 use:
record.transitionTo('deleted.saved');