I'm persisting my model from my controller via a call to this.get('model').save(). This results in a PUT to an endpoint that just returns a 200 message and nothing further. On the server side however, some custom rules are in place that are changing the data so that it's different than what Ember sent to the server. This puts my UI and my persistence tier into an inconsistent state.
What's the correct way to make sure the UI reflects what the correct state of the data after it was persisted to the server? Should my server-side endpoint return the updated model? I've tried just calling this.get('model').reload() after the save() but the UI isn't updating. When I did this I could see that it's asking and getting the new model from the server but as I said, it's not reflected in the UI.
I feel like there's some knowledge fundamental to Ember that I'm missing. Thanks for the help.
I guess that you are not waiting for the record to complete the updating process.
http://emberjs.com/api/data/classes/DS.Model.html#method_reload
So this would be:
this.get('model').reload().then(function() {
console.log("Now I am ready !");
})
Always remember that javascript is async.
Related
For example, let's take a simple web application with comments feature. In my understanding, when a user posts a new comment, the following would occur:
display UI loader;
update the front-end state;
send a fetch request to the API to post a new comment;
Wait for the response;
send another fetch request to the API to request the new list of comments;
waiting;
update the front-end state with new comments;
update UI to reflect the new state with a new comment;
And the user needs to wait while front-end app interacts with back-end on almost every data change. The same way we did it earlier with PHP/Python/Ruby, ajax, server-side rendering and templates.
That makes me think what's the point of adding so much front-end complexity with something like react, when the result is basically the same.
My question is: are there any alternative approaches to this? Is it possible instead to do the above case the following way:
user clicks to post a comment;
update the front-end state;
update UI to reflect the new state with a new comment;
sync front-end state with API DB in the background;
Well, as your question is tagged react, you could use the Apollo library (it is intended to work together with graphql on the backend) for data fetching. It offers a feature called Optimistic UI, which will be update the frontend with the respected result, until it receives an answer from the backend. If the expected result differs from the received one, the component will change the UI automatically to the real result. In case of an error, it will show an error message.
You definitely could, your first method is just way of doing it.
Apart from 'syncing' your front-end state, another method is also to just pre-emptively update the UI (step 7 & 8 in your first method) before doing step 3-6, and only reverse the action if the API call failed. This should allow for slightly better UX for the end-user too.
I get it that you think it's waste of time for users to wait until requests are successful. However, isn't it more important to stop users from keeping making bad requests to the server?
So, what I would do is just to stop fetching data from the database every after users make requests.
Fetching the DB data to begin with and store them in redux states
Make requests to the DB while holding users from doing anything
Make changes to the redux state if the requests are successful
But what you want to do could be done like this
Fetching the DB data to begin with and store them in redux states
Make changes to the redux state while making requests to the DB in the background
Depending on whether the requests fail or not, roll back the change users made from the redux state
I'm wondering how favorite, subscribe or like buttons work.
I don't understand something.
For exemple:
A user like a post with id 243.
A ajax request is sent to the server with the id of the post (243) [here comes back end stuff, the user's favorite list is updated, including that post] and the server sends back a success response.
Now, how I suppose to deal with modifying the like button to actually display that is liked (permanently, including refresh).
How can I achieve that in Vue JS. How things get updated? I don't understand this part.
If the server sends back a successful response you can increment the number that is already there.
This initial number is something you have gotten either through a prop, directly from the server or through an initial AJAX request.
If you want to "permanently" update the amount of likes on your button you have to persist it to a database(or some other storage medium). On you server you could have a route that accepts a post id as an argument and increment that specific user post:
/incrementlike/243
That is where you would make a POST ajax request to. Most of the time in an MVC framework you would have a controller action/method mapped to this route that holds the logic to respond to this call.
If you are interested in the part that happens after you make an AJAX request to the server to increment your like on the backend side, I suggest you read up on routing or MVC structure.
How you would do this is really done on a case by case basis. It really depends on a number of things, for example what your backend does to a post when it is liked.
If you would like a general 'explanation' to the process I attach it below, this is not really Vue specific, but the general idea is the same:
Frontend side:
Modify the local state of you post to set the proper flag, ex. post1.liked = true immediately when it is clicked, before sending the request to the server.
Make sure your GUI represent this change. ex. Base the color of the button on the property 'liked' of each post.
If a failure response it received from the server, notify the user and allow them to 'try again' or something similar.
When refreshing the page, make sure changes are fetched from the server, If you have done the backend part correctly, the modification of the state of the post will be correct in the data you receive from your backend (post1.liked will be true)
Backend side
When the request comes in, modify the state of the post the correct way and make sure that next time the post is fetched, the new state is sent.
I am very new to angular and this one is striking in my head a lot. So scenario is : Suppose angular http returns me model containing array of object like:
[{name:"Ankur",lastName:"aggarwal",updation_date:"23-08-2014"},{name:"xyz",lastName:"abc",updation_date:"29-08-2013"}]
Out of this updation_date is not required but coming for some reason. So is it right to update the array with third object without creation date like {name:"def",lastName:"jbc"} . Is it a good practice or array object model should be consistent?
Also what should be the approach? Update the model array first so binding take place instantly, then send it to the server or send it to server and get the updated object? Might be basic one but very new to angular and JMVC.
Is it a good practice or array object model should be consistent?
It depends , if backend expects all array entries to contain updation_date then you have no choice and are forced to add some sensible default value. However, if possible then avoid sending too much unnecessary data from backend since it impacts application performance(like data transfer, adding unnecessary logic to generate sensible default values, etc.)
Update the model array first so binding take place instantly, then
send it to the server or send it to server and get the updated object?
If the nature of your application permits reverting model value when save is unsuccessful then just go ahead with
0.Perform data validation, and make sure valid data is supplied to the backend.
1.Update model.
2.Send data to backend
3.If something bad happens then execute error handling depending on app needs
However if presenting consistent value in the GUI is uttermost importance(e.g. finance applications) then
0.Perform data validation, and make sure valid data is supplied to the backend.
1.Show some message to user like "saving"
2.Perform ajax request
3.If successful, update model, else execute error handling depending on app needs
It depend on your error handling.
As saving on the server-side might be not successful, you should take it into consideration.
My approach is to
Update angular object immediately
Then send AJAX request to server and
Wait for response. If error happen during server save, you shoulde:
revert values,
repeat AJAX
show information to user.
I have a backbone model. Now I want to update the model on server side, so I call model.save(); now as backbone.js makes an ajax call to server with PUT request. If the server fails to process this request, it sends some error code to client.
Now my question is, client has model's updated state, and server has an old state, both are inconsistent. Now on error() callback of my model.save() I want to revert the model to old state, how would I do it? Does backbone keeps copy of old state with it?
try using
oldMOdel = newModel.previousAttributes();
check out this
I read many Backbone.js tutorials, but most of them deal with static objects.
Of course, I have data on the server. I want a tutorial that shows how backbone.js can communicate with the server to fetch data, post data, etc.
This is .sync, right? I read the backbone.js documentation, but still fuzzy on how to use this feature.
Or can someone show me an example?
According to: http://documentcloud.github.com/backbone/#Sync
Backbone.sync is the function that Backbone calls every time it
attempts to read or save a model to the server.
But when? Where do I put the function? I don't know how to use it, and the documentation doesn't give any examples. When does the data get loaded into my models? I get to define when...right?
You never really have to look at .sync, unless you plan to overwrite it. For normal uses, you can simply call model.save() whenever you want and that will execute a post or put (depending on whether the record exists already). If you want to get the data from your backend, use collection.fetch()
You'll of course also need to specify a URL, do so through your collection attribute, collection.url
You can override Backbones native sync functionality if you override it:
Backbone.sync = function() {
//Your custom impl here
}
After that this function is called whenever you call a backbone function like .save() on models or .fetch() on collections. You do not have to care about data transport anymore.
I would suggest taking a look into Backbones source and look how the default sync function is implemented. Then create your own or adopt your server to support the native function.
They are not free, but the following screencasts both have a piece on backend work and how to send data to and get data from Backbone.
Tekpub is a 9 part screencast about asp.net MVC3, with the whole 6th part about using backbone to write an admin module to manage productions. it shows all about handling routing in MVC3 and sending & receiving data
Peepcode
http://peepcode.com/products/backbone-js about basic backbone stuff
http://peepcode.com/products/backbone-ii about interactivity
http://peepcode.com/products/backbone-iii about persistance (it's this third one you will need for server connection information).