Skip to main content
Added updateSafe information
Source Link
JoshGough
  • 974
  • 1
  • 8
  • 16
  • dbUrl and apiKey would be, of course, specific to your own MongoLab info
  • The array in this case is a group of distinct collections that you want individual ngResource-derived instances of
  • There is a createResource function defined (which you can see in the plunk and in the code below) that actually handles creating a constructor with an ngResource prototype.
  • If you wanted, you could modify the svc instance to vary its behavior by collection type
  • When you blur the input field, this will invoke the dummy consoleLog function and just write some debug info to the console for illustration purposes.
  • This also prints the number of times the createResource function itself was called, as a way to demonstrate that, even though there are actually two controllers, questionController and questionController2 asking for the same injections, the factories get called only 3 times in total.
  • Note: updateSafe is a function I like to use with MongoLab that allows you to apply a partial update, basically a PATCH. Otherwise, if you only send a few properties, the entire document will get overwritten with ONLY those properties! No good!

Full code:

HTML:

  <body>
    <div ng-controller="questionController">
      <h3>Question<h3>
      <h4>{{question.question}}</h4>
      Your answer: <input ng-model="question.value" saveable ng-blur="save(question)" />
    </div>
    
    <div ng-controller="questionController2">
      <h3>Question<h3>
      <h4>{{question.question}}</h4>
      Your answer: <input ng-model="question.value" saveable ng-blur="save(question)" />
    </div>    
  </body>

JavaScript:

(function() {
  var app = angular.module('savingServiceDemo', ['ngResource']);

  var numberOfTimesCreateResourceGetsInvokedShouldStopAt3 = 0;
  
  function createResource(resourceService, resourcePath, resourceName, apiKey) { 
    numberOfTimesCreateResourceGetsInvokedShouldStopAt3++;
    var resource = resourceService(resourcePath + '/' + resourceName + '/:id', 
      {
        apiKey: apiKey
      }, 
      {
        update: 
        {
          method: 'PUT'
        }
      }
    );

    resource.prototype.consoleLog = function (val, cb) {
      console.log("The numberOfTimesCreateResourceGetsInvokedShouldStopAt3 counter is at: " + numberOfTimesCreateResourceGetsInvokedShouldStopAt3);
      console.log('Logging:');
      console.log(val);
      console.log('this =');
      console.log(this);
      if (cb) {
        cb();
      }
    };
    
    resource.prototype.update = function (cb) {
      return resource.update({
              id: this._id.$oid
          },
          angular.extend({}, this, {
              _id: undefined
          }), cb);
    };

    resource.prototype.updateSafe = function (patch, cb) {
      resource.get({id:this._id.$oid}, function(obj) {
          for(var prop in patch) {
              obj[prop] = patch[prop];
          }
          obj.update(cb);
      });
    };

    resource.prototype.destroy = function (cb) {
      return resource.remove({
          id: this._id.$oid
      }, cb);
    };

    return resource;  
  }
  
  
  var dbUrl = "https://api.mongolab.com/api/1/databases/YOURDB/collections";
  var apiKey = "YOUR API KEY";
  
  var collections = [
    "user",
    "question",
    "like"
  ];  

  for(var i = 0; i < collections.length; i++) {
    var collectionName = collections[i];
    app.factory(collectionName, ['$resource', function($resource) {
      var resourceConstructor = createResource($resource, dbUrl, collectionName, apiKey);
      var svc = new resourceConstructor();
      // modify behavior if you want to override defaults
      return svc;
    }]);
  }
  
  app.controller('questionController', ['$scope', 'user', 'question', 'like', 
    function($scope, user, question, like) {
      $scope.question = {
        question: 'What kind of AngularJS object should you create to contain data access or network communication logic?',
        id: 1,
        value: ''
      };
    
      $scope.save = function(obj) {
        question.consoleLog(obj, function() {
          console.log('And, I got called back');
        });
      };
  }]);
  
  app.controller('questionController2', ['$scope', 'user', 'question', 'like', 
    function($scope, user, question, like) {
      $scope.question = {
        question: 'What is the coolest JS framework of them all?',
        id: 1,
        value: ''
      };
    
      $scope.save = function(obj) {
        question.consoleLog(obj, function() {
          console.log('You better have said AngularJS');
        });
      };
  }]);  
})();
  • dbUrl and apiKey would be, of course, specific to your own MongoLab info
  • The array in this case is a group of distinct collections that you want individual ngResource-derived instances of
  • There is a createResource function defined (which you can see in the plunk and in the code below) that actually handles creating a constructor with an ngResource prototype.
  • If you wanted, you could modify the svc instance to vary its behavior by collection type
  • When you blur the input field, this will invoke the dummy consoleLog function and just write some debug info to the console for illustration purposes.

Full code:

(function() {
  var app = angular.module('savingServiceDemo', ['ngResource']);

  var numberOfTimesCreateResourceGetsInvokedShouldStopAt3 = 0;
  
  function createResource(resourceService, resourcePath, resourceName, apiKey) { 
    numberOfTimesCreateResourceGetsInvokedShouldStopAt3++;
    var resource = resourceService(resourcePath + '/' + resourceName + '/:id', 
      {
        apiKey: apiKey
      }, 
      {
        update: 
        {
          method: 'PUT'
        }
      }
    );

    resource.prototype.consoleLog = function (val, cb) {
      console.log("The numberOfTimesCreateResourceGetsInvokedShouldStopAt3 counter is at: " + numberOfTimesCreateResourceGetsInvokedShouldStopAt3);
      console.log('Logging:');
      console.log(val);
      console.log('this =');
      console.log(this);
      if (cb) {
        cb();
      }
    };
    
    resource.prototype.update = function (cb) {
      return resource.update({
              id: this._id.$oid
          },
          angular.extend({}, this, {
              _id: undefined
          }), cb);
    };

    resource.prototype.updateSafe = function (patch, cb) {
      resource.get({id:this._id.$oid}, function(obj) {
          for(var prop in patch) {
              obj[prop] = patch[prop];
          }
          obj.update(cb);
      });
    };

    resource.prototype.destroy = function (cb) {
      return resource.remove({
          id: this._id.$oid
      }, cb);
    };

    return resource;  
  }
  
  
  var dbUrl = "https://api.mongolab.com/api/1/databases/YOURDB/collections";
  var apiKey = "YOUR API KEY";
  
  var collections = [
    "user",
    "question",
    "like"
  ];  

  for(var i = 0; i < collections.length; i++) {
    var collectionName = collections[i];
    app.factory(collectionName, ['$resource', function($resource) {
      var resourceConstructor = createResource($resource, dbUrl, collectionName, apiKey);
      var svc = new resourceConstructor();
      // modify behavior if you want to override defaults
      return svc;
    }]);
  }
  
  app.controller('questionController', ['$scope', 'user', 'question', 'like', 
    function($scope, user, question, like) {
      $scope.question = {
        question: 'What kind of AngularJS object should you create to contain data access or network communication logic?',
        id: 1,
        value: ''
      };
    
      $scope.save = function(obj) {
        question.consoleLog(obj, function() {
          console.log('And, I got called back');
        });
      };
  }]);
})();
  • dbUrl and apiKey would be, of course, specific to your own MongoLab info
  • The array in this case is a group of distinct collections that you want individual ngResource-derived instances of
  • There is a createResource function defined (which you can see in the plunk and in the code below) that actually handles creating a constructor with an ngResource prototype.
  • If you wanted, you could modify the svc instance to vary its behavior by collection type
  • When you blur the input field, this will invoke the dummy consoleLog function and just write some debug info to the console for illustration purposes.
  • This also prints the number of times the createResource function itself was called, as a way to demonstrate that, even though there are actually two controllers, questionController and questionController2 asking for the same injections, the factories get called only 3 times in total.
  • Note: updateSafe is a function I like to use with MongoLab that allows you to apply a partial update, basically a PATCH. Otherwise, if you only send a few properties, the entire document will get overwritten with ONLY those properties! No good!

Full code:

HTML:

  <body>
    <div ng-controller="questionController">
      <h3>Question<h3>
      <h4>{{question.question}}</h4>
      Your answer: <input ng-model="question.value" saveable ng-blur="save(question)" />
    </div>
    
    <div ng-controller="questionController2">
      <h3>Question<h3>
      <h4>{{question.question}}</h4>
      Your answer: <input ng-model="question.value" saveable ng-blur="save(question)" />
    </div>    
  </body>

JavaScript:

(function() {
  var app = angular.module('savingServiceDemo', ['ngResource']);

  var numberOfTimesCreateResourceGetsInvokedShouldStopAt3 = 0;
  
  function createResource(resourceService, resourcePath, resourceName, apiKey) { 
    numberOfTimesCreateResourceGetsInvokedShouldStopAt3++;
    var resource = resourceService(resourcePath + '/' + resourceName + '/:id', 
      {
        apiKey: apiKey
      }, 
      {
        update: 
        {
          method: 'PUT'
        }
      }
    );

    resource.prototype.consoleLog = function (val, cb) {
      console.log("The numberOfTimesCreateResourceGetsInvokedShouldStopAt3 counter is at: " + numberOfTimesCreateResourceGetsInvokedShouldStopAt3);
      console.log('Logging:');
      console.log(val);
      console.log('this =');
      console.log(this);
      if (cb) {
        cb();
      }
    };
    
    resource.prototype.update = function (cb) {
      return resource.update({
              id: this._id.$oid
          },
          angular.extend({}, this, {
              _id: undefined
          }), cb);
    };

    resource.prototype.updateSafe = function (patch, cb) {
      resource.get({id:this._id.$oid}, function(obj) {
          for(var prop in patch) {
              obj[prop] = patch[prop];
          }
          obj.update(cb);
      });
    };

    resource.prototype.destroy = function (cb) {
      return resource.remove({
          id: this._id.$oid
      }, cb);
    };

    return resource;  
  }
  
  
  var dbUrl = "https://api.mongolab.com/api/1/databases/YOURDB/collections";
  var apiKey = "YOUR API KEY";
  
  var collections = [
    "user",
    "question",
    "like"
  ];  

  for(var i = 0; i < collections.length; i++) {
    var collectionName = collections[i];
    app.factory(collectionName, ['$resource', function($resource) {
      var resourceConstructor = createResource($resource, dbUrl, collectionName, apiKey);
      var svc = new resourceConstructor();
      // modify behavior if you want to override defaults
      return svc;
    }]);
  }
  
  app.controller('questionController', ['$scope', 'user', 'question', 'like', 
    function($scope, user, question, like) {
      $scope.question = {
        question: 'What kind of AngularJS object should you create to contain data access or network communication logic?',
        id: 1,
        value: ''
      };
    
      $scope.save = function(obj) {
        question.consoleLog(obj, function() {
          console.log('And, I got called back');
        });
      };
  }]);
  
  app.controller('questionController2', ['$scope', 'user', 'question', 'like', 
    function($scope, user, question, like) {
      $scope.question = {
        question: 'What is the coolest JS framework of them all?',
        id: 1,
        value: ''
      };
    
      $scope.save = function(obj) {
        question.consoleLog(obj, function() {
          console.log('You better have said AngularJS');
        });
      };
  }]);  
})();
Added new plunk with alternative approach using only factory and ngResource
Source Link
JoshGough
  • 974
  • 1
  • 8
  • 16

However, you could also utilize factory and ngResource in a way that would let you reuse some of the common "saving logic", while still giving you the ability to provide variation for distinct types of objects / data that you wish to save or query. And, this way still results in just a single instantiation of the saver for your specific object type.

You could have a factory that creates an instance for you based on some parameters that differentiate that particular "instance" from others.

Note: This function could itself be a first-class angular factory, I thinkHere's a plunk.

The gist of the idea is this snippet:

function mongoLabResourceFactory(resourceService, resourcePath, resourceName, apiKey) {
    var resourcedbUrl = resourceService(resourcePath + '"https:/' + resourceName + '/:id', {api.mongolab.com/api/1/databases/YOURDB/collections";
        apiKey:var apiKey
    }, {
      = "YOUR update:API {KEY";
            method: 'PUT'
     var collections = }[
    });
"user",
    resource.prototype.update = function (cb) {"question",
        return resource.update({"like"
               ]; id: this._id.$oid
            },
      for(var i = 0; i < angularcollections.extend({},length; this,i++) {
                _id: undefined
            }), cb);
 var collectionName = };
collections[i];
    resource.prototypeapp.updateSafe = function factory(patchcollectionName, cb) {
        resource.get({id:this._id.$oid}['$resource', function(obj$resource) {
            for(var prop in patch) {
                obj[prop]resourceConstructor = patch[prop];
            }
            obj.updatecreateResource(cb);
     $resource, dbUrl, collectionName, }apiKey);
    };

   var resource.prototype.destroysvc = functionnew resourceConstructor(cb) {;
        return resource.remove({
     // modify behavior if you want to id:override this._id.$oiddefaults
        },return cb);svc;
    }]);
 
    return resource;
}

Then, in another module for my "api", I would do something like:Notes:

var dbUrl = "https://api.mongolab.com/api/1/databases/YOURDB/collections";
var apiKey = "YOUR API KEY";

angular.module("module.api", ["ngResource"]).factory("User", function($resource) {
  return mongoLabResourceFactory($resource, dbUrl, "user", apiKey);
}).factory("Favorite", function($resource) {
  return mongoLabResourceFactory($resource, dbUrl, "favorite", apiKey);
}).factory("Comment", function($resource) {
  return mongoLabResourceFactory($resource, dbUrl, "comment", apiKey);
});
  • dbUrl and apiKey would be, of course, specific to your own MongoLab info
  • The array in this case is a group of distinct collections that you want individual ngResource-derived instances of
  • There is a createResource function defined (which you can see in the plunk and in the code below) that actually handles creating a constructor with an ngResource prototype.
  • If you wanted, you could modify the svc instance to vary its behavior by collection type
  • When you blur the input field, this will invoke the dummy consoleLog function and just write some debug info to the console for illustration purposes.

Finally, in my controllers, I ask for specific collection objects by name:Full code:

(function() {
  var app = angular.controllermodule('userController''savingServiceDemo', ['ngResource']);

  var numberOfTimesCreateResourceGetsInvokedShouldStopAt3 = 0;
  
  function createResource($rootScoperesourceService, $scoperesourcePath, $dialogresourceName, UserapiKey) { 
    numberOfTimesCreateResourceGetsInvokedShouldStopAt3++;
    var resource = resourceService(resourcePath + '/' + resourceName + '/:id', use 
 User however    {
        apiKey: apiKey
      }, 
      {
        update: 
        {
          method: 'PUT'
        }
      }
    );

    resource.prototype.consoleLog = function (val, cb) {
      console.log("The numberOfTimesCreateResourceGetsInvokedShouldStopAt3 counter is at: " + numberOfTimesCreateResourceGetsInvokedShouldStopAt3);
      console.log('Logging:');
      console.log(val);
      console.log('this =');
      console.log(this);
      if (cb) {
        cb();
      }
    };
    
    resource.prototype.update = function (cb) {
      return resource.update({
              id: this._id.$oid
          },
          angular.extend({}, this, {
              _id: undefined
          }), cb);
    };

    resource.prototype.updateSafe = function (patch, cb) {
      resource.get({id:this._id.$oid}, function(obj) {
          for(var prop in patch) {
              obj[prop] = patch[prop];
          }
          obj.update(cb);
      });
    };

    resource.prototype.destroy = function (cb) {
      return resource.remove({
          id: this._id.$oid
      }, cb);
    };

    return resource;  
  }
  
  
  var dbUrl = "https://api.mongolab.com/api/1/databases/YOURDB/collections";
  var apiKey = "YOUR API KEY";
  
  var collections = [
    "user",
    "question",
    "like"
  ];  

  for(var i = 0; i < collections.length; i++) {
    var collectionName = collections[i];
    app.factory(collectionName, ['$resource', function($resource) {
      var resourceConstructor = createResource($resource, dbUrl, collectionName, apiKey);
      var svc = new resourceConstructor();
      // modify behavior if you needwant to nowoverride defaults
      return svc;
    }]);
  }
  
  app.controller('questionController', ['$scope', 'user', 'question', 'like', 
    function($scope, user, question, like) {
      $scope.question = {
        question: 'What kind of AngularJS object should you create to contain data access or network communication logic?',
        id: 1,
        value: ''
      };
    
      $scope.save = function(obj) {
        question.consoleLog(obj, function() {
          console.log('And, I got called back');
        });
      };
  }]);
})();

However, you could also utilize factory and ngResource in a way that would let you reuse some of the common "saving logic", while still giving you the ability to provide variation for distinct types of objects / data that you wish to save or query.

You could have a factory that creates an instance for you based on some parameters that differentiate that particular "instance" from others.

Note: This function could itself be a first-class angular factory, I think:

function mongoLabResourceFactory(resourceService, resourcePath, resourceName, apiKey) {
    var resource = resourceService(resourcePath + '/' + resourceName + '/:id', {
        apiKey: apiKey
    }, {
        update: {
            method: 'PUT'
        }
    });

    resource.prototype.update = function (cb) {
        return resource.update({
                id: this._id.$oid
            },
            angular.extend({}, this, {
                _id: undefined
            }), cb);
    };

    resource.prototype.updateSafe = function (patch, cb) {
        resource.get({id:this._id.$oid}, function(obj) {
            for(var prop in patch) {
                obj[prop] = patch[prop];
            }
            obj.update(cb);
        });
    };

    resource.prototype.destroy = function (cb) {
        return resource.remove({
            id: this._id.$oid
        }, cb);
    };
 
    return resource;
}

Then, in another module for my "api", I would do something like:

var dbUrl = "https://api.mongolab.com/api/1/databases/YOURDB/collections";
var apiKey = "YOUR API KEY";

angular.module("module.api", ["ngResource"]).factory("User", function($resource) {
  return mongoLabResourceFactory($resource, dbUrl, "user", apiKey);
}).factory("Favorite", function($resource) {
  return mongoLabResourceFactory($resource, dbUrl, "favorite", apiKey);
}).factory("Comment", function($resource) {
  return mongoLabResourceFactory($resource, dbUrl, "comment", apiKey);
});

Finally, in my controllers, I ask for specific collection objects by name:

app.controller('userController', function($rootScope, $scope, $dialog, User) {
  // use User however you need to now...
});

However, you could also utilize factory and ngResource in a way that would let you reuse some of the common "saving logic", while still giving you the ability to provide variation for distinct types of objects / data that you wish to save or query. And, this way still results in just a single instantiation of the saver for your specific object type.

Here's a plunk.

The gist of the idea is this snippet:

  var dbUrl = "https://api.mongolab.com/api/1/databases/YOURDB/collections";
  var apiKey = "YOUR API KEY";

  var collections = [
    "user",
    "question",
    "like"
  ];  

  for(var i = 0; i < collections.length; i++) {
    var collectionName = collections[i];
    app.factory(collectionName, ['$resource', function($resource) {
      var resourceConstructor = createResource($resource, dbUrl, collectionName, apiKey);
      var svc = new resourceConstructor();
      // modify behavior if you want to override defaults
      return svc;
    }]);
  }

Notes:

  • dbUrl and apiKey would be, of course, specific to your own MongoLab info
  • The array in this case is a group of distinct collections that you want individual ngResource-derived instances of
  • There is a createResource function defined (which you can see in the plunk and in the code below) that actually handles creating a constructor with an ngResource prototype.
  • If you wanted, you could modify the svc instance to vary its behavior by collection type
  • When you blur the input field, this will invoke the dummy consoleLog function and just write some debug info to the console for illustration purposes.

Full code:

(function() {
  var app = angular.module('savingServiceDemo', ['ngResource']);

  var numberOfTimesCreateResourceGetsInvokedShouldStopAt3 = 0;
  
  function createResource(resourceService, resourcePath, resourceName, apiKey) { 
    numberOfTimesCreateResourceGetsInvokedShouldStopAt3++;
    var resource = resourceService(resourcePath + '/' + resourceName + '/:id',  
      {
        apiKey: apiKey
      }, 
      {
        update: 
        {
          method: 'PUT'
        }
      }
    );

    resource.prototype.consoleLog = function (val, cb) {
      console.log("The numberOfTimesCreateResourceGetsInvokedShouldStopAt3 counter is at: " + numberOfTimesCreateResourceGetsInvokedShouldStopAt3);
      console.log('Logging:');
      console.log(val);
      console.log('this =');
      console.log(this);
      if (cb) {
        cb();
      }
    };
    
    resource.prototype.update = function (cb) {
      return resource.update({
              id: this._id.$oid
          },
          angular.extend({}, this, {
              _id: undefined
          }), cb);
    };

    resource.prototype.updateSafe = function (patch, cb) {
      resource.get({id:this._id.$oid}, function(obj) {
          for(var prop in patch) {
              obj[prop] = patch[prop];
          }
          obj.update(cb);
      });
    };

    resource.prototype.destroy = function (cb) {
      return resource.remove({
          id: this._id.$oid
      }, cb);
    };

    return resource;  
  }
  
  
  var dbUrl = "https://api.mongolab.com/api/1/databases/YOURDB/collections";
  var apiKey = "YOUR API KEY";
  
  var collections = [
    "user",
    "question",
    "like"
  ];  

  for(var i = 0; i < collections.length; i++) {
    var collectionName = collections[i];
    app.factory(collectionName, ['$resource', function($resource) {
      var resourceConstructor = createResource($resource, dbUrl, collectionName, apiKey);
      var svc = new resourceConstructor();
      // modify behavior if you want to override defaults
      return svc;
    }]);
  }
  
  app.controller('questionController', ['$scope', 'user', 'question', 'like', 
    function($scope, user, question, like) {
      $scope.question = {
        question: 'What kind of AngularJS object should you create to contain data access or network communication logic?',
        id: 1,
        value: ''
      };
    
      $scope.save = function(obj) {
        question.consoleLog(obj, function() {
          console.log('And, I got called back');
        });
      };
  }]);
})();
Added sample code and plunk
Source Link
JoshGough
  • 974
  • 1
  • 8
  • 16

One problem you may find, though,Here is that a service is intended to be created once and shared. That's great if you don't need any variation on its behavior.plunk with code modeled after your own starting example:

To avoid duplicationExample code:

var app = angular.module('savingServiceDemo', []);

app.service('savingService', function() {
  return {
    somethingOrOther: {
      save: function(obj, callback) {
        console.log('Saved:');
        console.dir(obj);
        callback(obj, {});
      }
    }
  };
});

app.directive('saveable', ['savingService', function(savingService) {
  return {
      restrict: 'A',
      link: function(scope) {
          scope.saveModel = function(question) {
              savingService.somethingOrOther.save(
                  {
                    id: question.id, 
                    answer: question.value
                  }, 
                  function(response, getResponseHeaders) {
                      // a bunch of post-processing
                  }
             );
          }
      }
  };
}]);

app.controller('questionController', ['$scope', function($scope) {
  $scope.question = {
    question: 'What kind of AngularJS object should you create to contain data access or network communication logic?',
    id: 1,
    value: ''
  };
}]);

The relevant HTML markup:

<body ng-controller="questionController">
  <h3>Question<h3>
  <h4>{{question.question}}</h4>
  Your answer: <input ng-model="question.value" saveable ng-blur="saveModel(question)" />
</body>

An alternative using only factory and the existing ngResource service:

However, you could play around with using factoriesalso utilize factory and servicesngResource in slightly different waysa way that would let you reuse some of the common "saving logic", while still giving you the ability to provide variation for distinct types of objects / data that you wish to save or query.

Example using MongoLab collections

You could have a factory that creates your service,an instance for you based on some parameters that differentiate that particular "instance" from others.

I will improve this answer tonight to be wrapped in a proper angular module / factory, but here's an approach I take when using MongoLab to store collections:

I've done something like this to make it easier to use MongoLab collections.

Then, in another module for my "api", I would do something like:

Note: you might be able to substitute .factory for .service here if you do need separate instances of the logic to communicate with your server. I haven't tried that yet, but will and let you know what I find out.

One problem you may find, though, is that a service is intended to be created once and shared. That's great if you don't need any variation on its behavior.

To avoid duplication, you could play around with using factories and services in slightly different ways. You could have a factory that creates your service, based on some parameters that differentiate that particular "instance" from others.

I will improve this answer tonight to be wrapped in a proper angular module / factory, but here's an approach I take when using MongoLab to store collections:

I've done something like this to make it easier to use MongoLab collections.

Then, in another module for my "api", I would do something like:

Note: you might be able to substitute .factory for .service here if you do need separate instances of the logic to communicate with your server. I haven't tried that yet, but will and let you know what I find out.

Here is a plunk with code modeled after your own starting example:

Example code:

var app = angular.module('savingServiceDemo', []);

app.service('savingService', function() {
  return {
    somethingOrOther: {
      save: function(obj, callback) {
        console.log('Saved:');
        console.dir(obj);
        callback(obj, {});
      }
    }
  };
});

app.directive('saveable', ['savingService', function(savingService) {
  return {
      restrict: 'A',
      link: function(scope) {
          scope.saveModel = function(question) {
              savingService.somethingOrOther.save(
                  {
                    id: question.id, 
                    answer: question.value
                  }, 
                  function(response, getResponseHeaders) {
                      // a bunch of post-processing
                  }
             );
          }
      }
  };
}]);

app.controller('questionController', ['$scope', function($scope) {
  $scope.question = {
    question: 'What kind of AngularJS object should you create to contain data access or network communication logic?',
    id: 1,
    value: ''
  };
}]);

The relevant HTML markup:

<body ng-controller="questionController">
  <h3>Question<h3>
  <h4>{{question.question}}</h4>
  Your answer: <input ng-model="question.value" saveable ng-blur="saveModel(question)" />
</body>

An alternative using only factory and the existing ngResource service:

However, you could also utilize factory and ngResource in a way that would let you reuse some of the common "saving logic", while still giving you the ability to provide variation for distinct types of objects / data that you wish to save or query.

Example using MongoLab collections

You could have a factory that creates an instance for you based on some parameters that differentiate that particular "instance" from others.

I've done something like this to make it easier to use MongoLab collections.

Then, in another module for my "api", I would do something like:

Source Link
JoshGough
  • 974
  • 1
  • 8
  • 16
Loading