简体   繁体   中英

Indented $http calls with AngularJS

I am trying to make multiple $http calls on an API interface to update my model.
Let me explain. I want to save a new object to my database, and once that object has been saved, I would like to get that object back and perform another $http call that updates another object. Here is my code:

Model:

var departmentSchema = mongoose.Schema({
    username     : { type:String,unique:true,required:true},
    email        : { type:String,unique:true,required:true},
    name         : { type:String, default:"", unique:true,required:true},
    stations     : { 
        type: [mongoose.Schema.Types.ObjectId], 
        ref: 'Station' 
    }
})

// Method that Pushes a Station to the department
departmentSchema.methods.pushStation = function(station) {
    var department = this;
    department.stations.push(station)
};  

API Route

router.put('/departments/:dep_id/stations/:stat_id', function(req, res, next) {
    Station.findOne({_id: req.params.stat_id}, function(err, data1){
       if (err) { return next(err); }

       var station = data1; 
        Department.findOne({_id: req.params.dep_id}, function(err, data2){
            if (err) { return next(err); }

            var department = data2;
            department.pushStation(station)
            res.json({success:true, department:department});
        });
    });
});  

Angularjs $http indented Calls

$scope.addNewStation = function(station){
    $http.post('/api/stations/', station)
    .then(function (data) {
        console.log(data)
        $scope.station = data.station;
        $http.put('/api/departments/' + $scope.department._id + '/stations/' + $scope.station._id, $scope.station)
        .then(function (data) {
            console.log(data);
        })
        bootbox.alert("Station Created Successfully");

    },function (err) {
        console.log(err)
    })
}  

I should point out that I have $scope.department in my URL, and this is because I get that data from a previous call, and I didn't want to crowd this section with unnecessary code.
So the problem is that when I execute $scope.addNewStation(...) , I am able to add the new Station successfully, the bootbox alert appears, the first console.log(data) is displayed, but then I get an error on the console stating: TypeError: Cannot read property '_id' of undefined and the second console.log(data) doesn't show up.
Please tell me what I a doing wrong here. I really need help with this. Thanks.

The object in the .then() callback is a response object, which includes status, data and other attributes. You should do something along the following:

$http.post('/api/stations/', station)
.then(function(response) {
    $scope.station = response.data.station;
})

Try this using angular promise, also check whether the scope variables station and department are correctly initialized.

var promise = $http.post('/api/stations/', station);

promise.then(
  function(data) {
     $scope.station = data.station;
        console.log($scope.station, $scope.department);
        $http.put('/api/departments/' + $scope.department._id + '/stations/' + $scope.station._id, $scope.station)
        .then(function (data) {
            console.log(data);
        });
});

I would recommend using an async waterfall.

Here's an example (on the backend):

var waterfall = require('async-waterfall');
waterfall([
    function(callback){
        callback(null, 'param1');//the first parameter is the error - if there is one
    },
    function(param2, callback){
        callback(null, 'param2');
    }
], function(err, result){
    // if no errors send response back to angular
})

This way you can do without the nested calls. For better examples, see the link I provided.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM