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?

+3


source to share


3 answers


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.

+2


source


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();
    
          

+1


source


@ 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();

      

0


source







All Articles