Question

I'm working with angular resources trying to use the angular $save function.

By default $save sends the model back to the service URL. However, it looks like it expects the model to be returned to the service (my model is empty if I don't do this). I was wondering what the best way to return messages and errors to the controller is.

My solution was to create a new class in my PHP that has an errors array that stores any errors encountered in processing and a field that stores the model for returning. It's then send back and processed in the call-back function:

$scope.ApplyChanges=function(){
   console.log("saving...");
    $scope.user.$save(function(data){
      console.log(data);
      if (data.errors.length>0){
         for (error in data.errors){
            $scope.alerts.push({type:'danger', msg: data.errors[error].msg});
         }
         $scope.user=User.get({id:data.data.UserName});
      } else {
         $scope.user=User.get({id:data.data.UserName});
         $scope.alerts.push({type:'success', msg: "User data saved successfully"});
      }
    }, function(err){
         $scope.alerts.push({type:'danger', msg: "There was a problem saving your data: " + err});
    });

these lines here: $scope.user=User.get({id:data.data.UserName}); I had to use because if I just assigned my $scope.user to data.data, user was no longer using the service and I would get an error when I tried to ApplyChanges again.

So, is there a way to do this more seemlessly? As it is I have to make an additional call back to get the model. Should I send an error only if there's an error and then have an additional callback to get the model? Is there a better way?

Was it helpful?

Solution

First of all, your server should return errors with relevant HTTP error status codes (see 4xx and 5xx codes). That way, you only handle errors in the error callback:

function onError (response){
    switch (response.status) {
    case 400:
    case 404:
    //etc... 
        response.data.errors.forEach(function(error){
            $scope.alerts.push({type:'danger', msg: error.msg});
        });
        break;
    case 500:
        $scope.alerts.push({type:'danger', msg: "There was a problem saving your data: " + response.data});
        break;
    }
}

That said, if $scope.user is a $resource instance, then you do not have to get it again from the server, the $save() method will not change the object.

To copy values from the 'user' object retrieved from the server into the $scope.user just use angular.extend()

angular.extend($scope.user, data) //this updates $scope.user with data attributes.

Is worth noting that angular.extend does not perform a deep copy, if needed, use jQuery.extend:

jQuery.extend(true, $scope.user, data)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top