Your code is speaking to me...

Hopefully this blog stays at a "micro" level. I want to keep this short and sweet. This morning I came across this code (tried to keep is as pure as when I found it):

Model = $resource('/api/something'); 

Model.query.$promise.then(function (data) {  
   $scope.data = data;
  }, function (err) {
    $log.debug('Error', err);
});
 function save() {
   Model.save(data).$promise
    .then(
      function(newData) {
        $state.go('model.show', {
          modelID: newData.ModelID
        });
      },
      function(error) {
        var errorMsg = '';

        // display error notification
        if (typeof error === 'object') {
          if (error.data !== undefined || error.data.errorMsg === '' || error.data.errorMsg === undefined) {
            errorMsg = 'An error has occurred !';
          } else {
            errorMsg = error.data.errorMsg;
          }
        } else {
          errorMsg = error;
        }
        growlNotifications.add(errorMsg, 'danger');
  });
}

What could I infer from this code?

  1. The developer didn't take the time to learn about ngResource.

    So how do I know this? I can tell by the fact he/she is consistently incorrectly using the $resource API. In very few instances should you use the $promise property directly (I use it for loading indicators). $resource provides an api for a reason. The developer should be using query(data, success, error) or save(data, success, error) or if he is a member of my team he better be using $save or have an excuse from mom explaining why.

  2. The developer doesn't really understand, or trust, the API he is calling.

    The developer more than likely is dealing with an inconsistent api. Meaning the API doesn't always return the same thing. Sometimes its an object, other times its a string.. and if you are really unlucky it could be null. Needless to say this is really bad, your API should be consistent. If it's not make it.

    The API changing probably explains why you see the save versus $save. If I had to place $20 on it I would say if I posted { user: nick } I would get back {data: {user: nick} }. Yet again this is bad for many reasons. Since the data type changes on the way back I can't use $resource normally and I am forced to write bad code.

  3. CPP - Copy Paste Programmer. I'm willing to place another $20 on the fact that this developer saw the query() call and copy and pasted it to create the save function. For those who know the $resource api it returns smart objects that can save themselves (2. could be the reason they did not use this, but it doesn't not explain the user of $promise again).

So enough complaining.. how would you have done it ?

Model = $resource('/api/something');  
//embrace the technology you are using
//new up a model and use this as an object
$scope.model = new Model();
$scope.models = [];
Model.query(function(data) {  
  //inplace concat
  $scope.models.push.apply($scope.models, data);
}, function(err) {
  //changed this from log.debug to use 
  //the built in notifications
  //let the user know something went wrong..
  //dont hide it from them
  growlNotifications.add('Error loading data', 'danger');
});


function save() {  
  //notice we now can use $save
  // which performs a post and update the object
  // with the response
  // Yes.  I fixed the API or I wrote a custom 
  // transformResponse function
  $scope.model.$save(
    function(newData) {
      $state.go('model.show', {
        modelID: newData.ModelID
      });
    },
    function(error) {
      var errorMsg = 'An error has occurred!';
      // display error notification
      //remove all that crazy logic
      if (error && error.data && error.data.errorMsg) {
        errorMsg = error.data.errorMsg;
      }
      growlNotifications.add(errorMsg, 'danger');
    });
}

OCD is now at rest... and I can move on.

Nick Capito

Professional developer in all things generic. Good at AngularJS, CSS3 , Sass, .NET, Azure, Node. Love dogs. In an alternate live I would have been an American Cesar Millan.

Richmond, VA http://nixo.us