1

I have a model that I am using to hold my data in angular:

var FuelProcessingModel = function (carrierService) {
    this.myArray = [];
};

That model has an array of MyObjects that I get from the DB:

var MyObject = function () {
    //stuff
}

I update this using a REST call:

$scope.add = function () {
        var myObject = new MyObject();
        $scope.model.MyObjects.push(myObject);
        service.add(myObject);
    };

Which I use a service to hit the Server:

this.add = function (myObject) {
        $http({
            method: "POST",
            url: "theServer",
            data: myObject
        });
    }

The REST service just adds to the database, It doesn't return anything. I need to reload the data from the database after the update is finished, so that my records now have all newly associated ID's and pertinent data.

I cannot just do:

window.location.reload();

The user starts by selecting a value from a drop down list to decide which list of data they start off seeing. I cannot / do not want to pass the value to it, mainly because it is in its own partial view, with its own controller, because it is used on many pages.

I tried doing:

$scope.add = function () {
        //same as above
        //this
        service.get().then(function(result) { $scope.model.myArray = result.data; });
    };

Obviously the problem here is the promise isn't complete before the DOM reloads the page. So the user saw themself add an item to the array and it vanished.

Do I want to load the page after the promise is complete? (How would I do that?) should I return the updated data from the REST service and reset the current value? (seems like the same promise issue)

Is there a better practice that I do not know about?

UPDATE

For Bergi:

this.get = function (key) {
        return $http({
            method: "GET",
            url: "theServer" + key
        })
            .success(function (data) {
                return data;
            });
    }
Robert
  • 4,306
  • 11
  • 45
  • 95

2 Answers2

2

I think you want to chain your two promises:

$scope.add = function () {
    var myObject = new MyObject();
    $scope.model.MyObjects.push(myObject);
    return service.add(myObject).then(function() {
        return service.get();
    }).then(function(result) {
        $scope.model.myArray = result.data;
    });
};

and

this.add = function(myObject) {
    return $http({
//  ^^^^^^ return a promise here
        method: "POST",
        url: "theServer",
        data: myObject
    });
};
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I updated my code, are you saying I should put the return of the first promise where the comment is? – Robert Apr 01 '15 at 19:34
  • @Robert: Yes, [no deferreds needed](http://stackoverflow.com/q/23803743/1048572) at all. – Bergi Apr 01 '15 at 19:37
  • With my code above, would you have two return statements? Could you put an example of it? – Robert Apr 01 '15 at 19:59
1

You can wrap your service call in a deferred promise, and on return success re-init your data from the controller..

$scope.add = function () {
    var myObject = new MyObject();
    $scope.model.MyObjects.push(myObject);
    service.add(myObject).then(function (response) {
       // here's where you'd do whatever you want to refresh your model
    }),
    function (err) {console.log(err);};
};

And the service:

this.add = function (myObject) {

    var deferred = $q.defer();

    $http({
        method: "POST",
        url: "theServer",
        data: myObject,
        success: function (response) {
           deferred.resolve(err);
        },
        error: function (err) {
           deferred.reject(err);
        }
    });

    return deferred.promise;
}
Joshua Ohana
  • 5,613
  • 12
  • 56
  • 112
  • in order to use this my REST controller would have to send back some sort of acknowledgement that it was successful right? – Robert Apr 01 '15 at 18:37
  • @Robert, correct-a-mundo, for simplicity you could just send back a 200 OK on success or 400 on failure. What's your back-end in? – Joshua Ohana Apr 01 '15 at 18:40
  • Don't use the deferred antipattern! No need to instantiate deferreds here! Btw, you're not returning anything? – Bergi Apr 01 '15 at 18:48
  • @Bergi I am not returning anything from the server, currently but I can change that. – Robert Apr 01 '15 at 18:50
  • @Robert: That comment was aimed at JoshuaOhana, his service function doesn't really work – Bergi Apr 01 '15 at 18:52
  • @Bergi TIL :) Thanks and agreed (now that I've researched), feel free to post the proper answer and I'll upvote – Joshua Ohana Apr 01 '15 at 19:00
  • @JoshuaOhana: Already did :-) My answer calls `service.add` *and* `service.get` though, not sure whether that's a good practise in angular. – Bergi Apr 01 '15 at 19:03
  • Where does $q come from, I injected it into my service and it errored – Robert Apr 01 '15 at 19:11
  • @Robert, AngularJS...... .factory('myService', ($q, $http... see https://docs.angularjs.org/api/ng/service/$q – Joshua Ohana Apr 01 '15 at 19:23