Angular reload resource that is being viewed
I think this sounds like an obvious question, but my brain seems to be a little on fire.
I have a resource
Book = $resource("/books/:id", {id: "@id"});
book = Book.get(1);
I want to update an object to receive changes from the server. I know I can do this by repeating it book = Book.get(book.id)
, but that would mean that everything on the page that is viewing book
will be temporarily zeroed out until the request returns and the functions that are running on it may crash.
I want to add a reload method to instances that update any changed fields after the request returns from the server. My best attempt:
$reload = function() {
var model = this;
Book.get(model.id, function(data) { // success
angular.forEach(data, function(value, key) {
model[key] = value;
}
}
}
Two questions a) Is this the "angular" way, or is there a more elegant way? a) How do I add this refresh method when defining a resource so that it is included in every instance created?
source to share
Try a prototype prototype:
var Book = $resource("/books/:id", {id: "@id"});
Book.prototype.reload = function(callback) {
return this.get(this.id, callback);
}
var book = Book.get(1);
book.reload(function(data){console.log(data);});
thanks to: @ mathew-berg (Matthew Berg) for correcting my code.
source to share
A few thoughts:
- How is your model structured? From the $ resource docs: "Having an empty object does not render, as soon as data comes in from the server, then the object is populated with data and the view automatically re-renders the new data."
-
Group your own API interactions in an Angular service so you can control the async behavior:
yourApp.factory('BookService', function($q) { //Other API calls here function reload() { var deferred = $q.defer(); $http.get('/someUrl'). success(function(data, status, headers, config) { //Massage your data here... then deferred.resolve(data); }). error(function(data, status, headers, config) { deferred.reject('There was a problem updating the books'); }); return deferred.promise; } return { reload: reload } }); //In your conttroller or directive that holds your model books = BookService.reload();
source to share
@ num8er's solution won't even work without crashing for me. Maybe we are using different angular versions? (I'm on 1.4.x at the moment). In particular, I had to change get()
to $get()
, but I also wanted to reload the object without missing its own callback to grab it everywhere. so I added this to the inside.
I had to do:
var Book = $resource("/books/:id", {id: "@id"});
Book.prototype.reload = function() {
var book = this;
book.$get(book.id, function (new_book) {
book = new_book; // replace old book object with newly reloaded one
});
};
var book = Book.get(1);
book.reload();
source to share