Does anybody know how can I handle this?
So, I execute the following code in my controller:
this.get('newEvent').save();
It gets my data and sends it to the server. Here's some data
Request URL:http://localhost:1337/api/v1/events/53a9cfee701b870000dc1d01
Data to send:
event:{
date: "Mon, 18 Aug 2014 07:00:00 GMT"
host: "Host"
repeatable: true
title: "Event name"
}
But for success I need to know the model id on my server which is normally included to the event object I send. Do you know any solutions? By the way DELETE request doesn't exclude id from the event object
You can easily override the saving behavior to include the id by overwriting the updateRecord hook in the RestAdapter: https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L457 to pass includeId: true the same way createRecord does https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L436
There are a few ways of handling this, and it comes down to personal preference. But I would recommend altering your backend code to pull the ID from the URL. Normally when you define the put request, you do it like /events/:event_id. If you did it this way on the backend, there's no need for it to be in your events object that's send over.
api/v1/events/53a9cfee701b870000dc1d01
You can capture this on the server by looking at the URL parameter that's sent over. If you're using Express on the backend, you can get the ID straight from the URL with little effort. I can't comment yet, but let me know your backend structure, and I can point you in the right direction. Possibly include the PUT request you wrote on the back end as a point of reference.
The other thing that you can do(not recommended, but will work) is to store a temporary id before doing the save.
var id = this.get('newEvent');
this.get('newEvent').set('temp_id', id).save();
And then you can access the temp_id on the server call without checking the param_id on the server call.
Related
I working on a service which scrapes specific links from blogs. The service makes calls to different sites which pulls in and stores the data.
I'm having troubles specifying the url for updating the data on the server where I now use the verb update to pull in the latest links.
I currently use the following endpoints:
GET /user/{ID}/links - gets all previously scraped links (few milliseconds)
GET /user/{ID}/links/update - starts scraping and returned the scraped data (few seconds)
What would be a good option for the second url? some examples I came up with myself.
GET /user/{ID}/links?collection=(all|cached|latest)
GET /user/{ID}/links?update=1
GET /user/{ID}/links/latest
GET /user/{ID}/links/new
Using GET to start a process isn't very RESTful. You aren't really GETting information, you're asking the server to process information. You probably want to POST against /user/{ID]/links (a quick Google for PUT vs POST will give you endless reading if you're curious about the finer points there). You'd then have two options:
POST with background process: If using a background process (or queue) you can return a 202 Accepted, indicating that the service has accepted the request and is about to do something. 202 generally indicates that the client shouldn't wait around, which makes sense when performing time dependent actions like scraping. The client can then issue GET requests on the first link to retrieve updates.
Creative use of Last-Modified headers can tell the client when new updates are available. If you want to be super fancy, you can implement HEAD /user/{ID}/links that will return a Last-Modified header without a response body (saving both bandwidth and processing).
POST with direct processing: If you're doing the processing during the request (not a great plan in the grand scheme of things), you can return a 200 OK with a response body containing the updated links.
Subsequent GETs would perform as normal.
More info here
And here
And here
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 });
I created a pass and can register device to my server. I also updated this pass by changing some contents and insert a new row of pass to pass table. But why in console, last updated (null) ? this is what I get from console:
Apr 6 10:30:29 CamMobs-iPod4 passd[21] <Warning>: Get serial #s task (for device b6511c0dd47d04da449ce427b27fea74, pass type pass.cam-mob.passbookpasstest, last updated (null); with web service url http://192.168.1.202:8888/passesWebserver/) got response with code 200
Whenever a .pkpass bundle is accepted or replaced in a device's Passbook library, Passbook will tag the pass with a last updated attribute.
This attribute is typically set by the Last-Modified header a webserver sends the first time the pass is downloaded, and your web service sends with every response to the "Get Latest Version of a Pass" response.
Passbook also polls your web service using a "Getting the Serial Numbers for Passes Associated with a Device" method for serialNumbers, using the deviceLibraryIdentifier and passTypeIdentifier as criteria.
The "Getting the Serial Numbers for Passes Associated with a Device" response should contain a tag lastUpdated, indicating when the results of this query were last changed (I.e. when was the last time that a pass using the passTypeIdentifier registered to this deviceLibraryIdentifier was last updated).
However, the very first time Passbook sends a "Getting the Serial Numbers for Passes Associated with a Device", it will not have received a lastUpdated tag which is why it is showing null in your console log. Also, sending a lastUpdated tag is optional, so if it is not present, or if it is not sent correctly, then you will always see last updated (null) for this request.
You are free to use whatever you like as a lastUpdated tag. The simplest solution to implement is a unix timestamp as there is no need to mess around with date formats.
I have a web application that will be doing some processing with submitted data. Instead of making the user wait for what will take at least a few seconds, maybe up to a few minutes during heavy load, I would like to know if there is some way to, within coldfusion, have processing that just occurs on the server.
Basically, the data would be passed to the server, and then the user would be redirected back to the main page to allow them to do other things, but not necessarily be able to see the results right away. Meanwhile, the processing of the data would take place on the server, and be entered into the database when complete.
Is this even possible within coldfusion, or would I need to look into using code that would receive the data and process it as a separate program?
ColdFusion 8 introduced the cfthread tag which may assist you.
<cfthread
required
name="thread name"
optional
action="run"
priority="NORMAL|HIGH|LOW"
zero or more application-specific attributes>
Thread code
</cfthread>
To do this reliably, you can use a database table as a job queue. So you when the user submits the data you insert record into the database indicating there is some work to be done. Then you create a scheduled task in the CF Administrator that polls a script that gets the next job from the queue and does the processing you describe. When complete it can update the database and you can then alert your user that there job is complete.
Make sense?
Another option that will possibly work for you is to use AJAX to post the data to the server. This is a pretty easy method to use, since you can use pretty much the exact same CF code that you have now and instead only need to modify the form submitting page (and you could even use some unobtrusive javascript techniques to have this degrade gracefully if javascript isn't present).
Here's an example using jQuery and BlockUI that will work for unobtrusively-submitting any form on your page in a background thread:
<script>
$(function () {
$("form").on("submit", function (e) {
var f = $(this);
e.preventDefault();
$.ajax({
method: f.attr("method"),
url: f.attr("action"),
data: f.serialize(),
beforeSend(jqXHR, settings) {
f.blockUI({message: "Loading..."});
},
complete(jqXHR, textStatus) {
f.unblockUI();
},
success: function (data, textStatus, jqXHR) {
// do something useful with the response
},
error: function(jqXHR, textStatus, errorThrown) {
// report the error
}
});
});
});
</script>
You should combine all three of these answers to give yourself a complete solution.
Use CF Thread to "kick off" the work.
Add a record to the DB to tell you the process is underway.
Use Ajax to check the DB record to see if the work is complete. When
your thread completes update the record - Ajax finds the work
complete and you display some message or indicator on the user's
screen so they can go on to step 2 or whatever. So each of these
answers holds a clue to a complete solution.
Not sure if this should be an answer or a comment (since I'm not adding anything new here).
We use an CF event gateway for this. The user submits a file via a web form and the event gateway monitors that upload directory. Based upon the file name the gateway knows how it should process the file into the database. This way the only real delay the user faces is the time for the file to actually transmit from their machine up to the server. We however have no need to inform the user of any statuses related to the process though could easily see how to work that into things if we did.