I'm using the new router and ember data rev 11.
I have a need to force ember-data to re-load data for a record from the server. Using App.MyRecord.find(2) in setInterval function loads the data from the client local store.
How can I reload the data from the server?
I just pushed record.reload() to Ember Data. This will ask the adapter to reload the data from the server and update the record with the new data.
Constraints:
You can only call reload() on a record if it has completed loading and has not yet been modified. Otherwise, the returned data will conflict with the modified data. In the future, we will add support for a merge hook to address these sorts of conflicts, which will allow reload() in more record states.
If you call reload() and change or save the record before the adapter returns the new data, you will get an error for the same reason. The error currently looks something like Attempted to handle event 'reloadRecord' on <Person:ember263:1> while in state rootState.loaded.updated.uncommitted.. Basically, this means that your record was in the "updated but uncommitted" state, and you aren't allowed to call reload() outside of the "loading and unmodified" state.
Related
Every time an ajax call is made. I need to get the current values of items to the session state.
I know I can do this from JS in the apex.server.process call by setting appropriate "pageItems" Parameter.
But is there a way to set the items current value to session in the plsql block of the ajax process instead of doing it on the client-side using pageItems parameter in apex.server process
In short : I need to know,in the server, the current client-side value of items in the page every time a call is sent to the server using ajax. And this should be done without any client-side code involved.
I have a simple DBExpress application using a SQLite database on C++ builder XE3.
The UI is having a few DBGrids and DBNavigators. The DBGrids are connected to TDataSources that are connected to TClientDataSets. The TClientDataSets gets data from TDataProviders, that are getting data from a TSQLDataSet. Everyting connected to a TSQLConnection.
The application works fine except when data is posted by another db component, not related to the application. To get the new 'remote' data, I have to click the Refresh button on the navigator twice(2).
I'm getting the same behavior with the following code:
mClientDBSession.insertImageFile(getFileNameNoPath(f), "Note..");
DBNavigator1->BtnClick(nbRefresh);
DBNavigator1->BtnClick(nbRefresh);
The mClientDBSession is a database object not related to DBExpress. The insertImageFile inserts a db record directly into the SQLite database and is synchronous, so i know the DB got the data after the function exits.
Oddly, if I don't call the BtnClick(nbRefresh) twice, the data is not updated , afaik from looking at the DBGrid.
Ideally I would have a timer automatically updating the DBExpress components with new server data every so often.
I am experimenting with turning a more traditional ember-data based app into a real-time app that uses websockets to keep multiple instances in sync.
My first attempt involves sending any updated record back to all open sessions that have accessed the record so that they all can have the latest copy. This includes the session that initiated the change. This means that after I call record.save() in the client, I get back the updated copy both from the REST API and the websocket. The client-end of the websocket simply calls store.pushPayload(data) to update the store.
This causes problems because the record might be inFlight at the time, and I get the error:
Attempted to handle event `pushedData` on [...] while in state root.deleted.inFlight.
I have several ideas:
Somehow prevent the client from receiving its own records back and only send them to other websocket connections.
Somehow synchronize access to the store so that when I call pushPayload the affected records are not in-flight.
Both of these seem rather complicated and I was hoping there's an established means of keeping multiple Ember apps up-to-date.
Update
Demo: http://jsbin.com/ogorab/311/edit
I'm trying to build a simple chat room that updates in realtime using Faye/Websockets. Messages are posted using regular REST, but there is also a subscription via Faye to /messages/created, which uses store.pushPayload to push the new messages.
Now the following scenario happens and I can see where it goes wrong but I have no clue how to solve it:
User submits chat message
ChatController handles the submit, calls createRecord with the chat message, and subsequently #save
The chat messages is instantly shown in the chat (triggered by createRecord). Note that no id has been assigned yet.
A REST request is send to the server
The server first publishes the message to Faye
The server responds to the REST request
Before the ajax call is resolved, a message has arrived at /messages/created
The message is again inserted in the view (it should be merged with the original message of course, but that one still hasn't been assigned an id)
The ajax call is resolved, and the id of the original message is assigned.
This results in duplicate messages, in the following order:
[message via createRecord, will resolve via ajax response]
[message inserted via pushPayload/Faye]
I hope you can understand so far. A solution would be to have Faye wait for the save call to resolve before pushing the payload. Unfortunately I don't have a reference to the record that is being saved (happens in a controller, faye subscription is set up in ApplicationRouter).
Also I would like this to work in a generic way:)
Finally found a solution for this, but other suggestions are still welcome.
Turns out that Store#didSaveRecord updates the id after the record is saved. By overriding this method (and then calling super, in that order), we can first check if a record for that id already exists:
App.Store = DS.Store.extend
didSaveRecord: (record, data) ->
# This will remove any existing records with the same id
#getById(record.constructor, data.id)?.unloadRecord()
#_super(record, data)
Is there a way to add records to a client model and indicate to Ember that these records are already on the server side?
So, for instance if my Person model has records for "Peter" and "Paul" but then later the server adds "Mary" and my client becomes aware of that in a non ember-data sort of way. I'd like to be able to have the client add "Mary" in a way that will not cause state problems with the subsequent interactions.
For those that must know the "use case" ... I'm trying to:
have the first request to findAll() for a given model to pull the full set of data back from the server
have subsequent requests in a session call a custom AJAX request that only returns differences to the resultset since that last request
I want to be able to push these differences into the client model without screwing up it's "state"
Sometimes we create and update EmberData records on the client with data from websockets. In this case, the changes are already on the server, so we just want to make the changes on the client without changing state, etc, exactly as you describe.
When we create new records on the client, we push them into the store, e.g.:
this.store.push('post', { id: 1, body: 'Ember!' });
And, when we update existing records on the client, we update them in the store, e.g.:
this.store.update('post', { id: 1, hidden: true });