Is this architecture still valid under Angular 1.2 and above - javascript

There are many code examples using $resource out there. I came across this one, and the code is quite clearly laid out: https://github.com/apotry/stockwatch
I like this example because:
It interacts with a Rails backend, which is how I am using Angular
It uses $resource
It is using a non-rest route (ohlc)
The code is quite clean
To call the functions defined is quite simple as shown in the controller code below, but is it a good idea to embed the save in the factory?
My question is: now that Angular 1.2+ includes promises, is this type of code still valid and considered a good practice? How would this code respond to an error state?
Here the resources are defined
app.factory('Stock', ['$resource', function($resource) {
function Stock() {
this.service = $resource('/api/stocks/:stockId', {stockId: '#id'}, {'update': { method: 'PUT' }});
};
Stock.prototype.all = function() {
return this.service.query();
};
Stock.prototype.delete = function(stId) {
return this.service.remove({stockId: stId});
};
Stock.prototype.create = function(attr) {
return this.service.save(attr);
};
Stock.prototype.update = function(attr) {
return this.service.update(attr);
};
Stock.prototype.ohlc = function(stId) {
return $resource('/api/stocks/:stockId/ohlc', {stockId: '#id'}).get({stockId: stId});
}
return new Stock;
}]);
Here is an example of the delete, create and a custom route (ohlc):
$scope.requestOHLC = function (stockid) {
return Stock.ohlc(stockid);
}
$scope.createStock = function() {
$scope.fetchYahooFinanceData($filter('uppercase') ($scope.newCompany["symbol"])).then(function(result) {
$scope.error = false;
$scope.stocks.push(Stock.create(result));
$scope.newCompany = '';
}, function(error) {
$scope.error = true;
});
};
$scope.deleteStock = function(id, idx) {
Stock.delete(id);
$scope.stocks.splice(idx, 1);
};
EDIT
I am trying to work out a simple and clear practice for using $resource based rest routes in angular.
Different from the above code, but based on it. Assume the code below uses a service which is basically the same as the factory above. In this example I call one REST resource to create a new resource (rails table entry), and then pass the newly created id to another call. Note that createPanelHeader references the $scope.selector.paneldata.primer3_parameter_id scope variable. Not sure if this is a good practice either.
I found this would not work unless I uses $promise.then but this seemed a bit convoluted. Am I on the right track?
// Section: Create Panel header
createPrimer3Parameter = function() {
primer3_parameter = Primer3Parameter.create().$promise.then(function(primer3_parameter){
$scope.selector.paneldata.primer3_parameter_id = primer3_parameter.id;
createPanelHeader();
}, function() {
alert('Error creating primer3parameter');
})
};
COMMENT
I am really just trying to work out a simple method for accessing REST resources from a Rails API, with at most 1 level of nesting. I think I am missing something as it seems remarkably difficult.
What I am hearing so far is not to use $resource, even under 1.2. That I should instead use raw $http or Restangular.
Also, there seem to be some 1.2 changes that affect Restangular. The solution feels a bit like a hack to me:
https://github.com/mgonto/restangular#using-values-directly-in-templates
UPDATE
I didn't really come away 100% clear, so I have posted a Bounty: https://bountify.co/write-an-angular-service-for-these-rails-routes-using-restangular

is this type of code still valid and considered a good practice?
This code is valid, but considered deprecated as of 1.2.0-rc3. It will work in all version of angular 1.2 and 1.3 up to but not including 1.3.0-beta10, where automatic promise unwrapping has been removed.
$scope.stocks.push(Stock.create(result));
In the line above you've created an array of promise objects on $scope. Then in index.html.erb you are referencing the promise directly via the stock iterator:
<li ng-repeat="stock in stocks">
<div id='symbol'>
{{stock.symbol}}
</div>
The non-deprecated way of handling promises does not allow you to bind directly to the promise like this.
How would this code respond to an error state?
The app is handling errors here:
}, function(error) {
$scope.error = true;
});
and here:
<div ng-show="error">
There was a problem with the Yahoo Finance API. Please try again later.
</div>
For error handling, you're not binding with a promise directly so this works fine in all versions of angular.
A better way?
First, shelf the javascript directory structure in the stockwatch example. Then, follow this directory structure instead. Finally, integrate Restangular into your project. Create a stockModel factory that internally instantiates a Restangular object, but returns the object that will be populated later after the promise resolves (model). Instead of binding a promise in your partial, bind the unpopulated result object.
.factory('stocksModel', function (Restangular) {
var model = {};
var rest_stocks = Restangular.all('stocks');
model.doSomethingRESTful = function (...) {
// return a promise in case the controller needs it
return rest_carts.some_restangular_method(...)
.then(function() {
model.some_data_which_was_acquired_RESTfully = ...;
});
};
return model;
});
In your controller:
$scope.stocks = stocksModel;
In your partial:
{{stocks.some_data_which_was_acquired_RESTfully}}

To be blunt
No. If possible, I would improve the code so that is it more maintainable and update to date with Angular. Let me explain why it is a good idea. . .
Why are you making your life so hard?
Angular is a wonderful framework that lets you tackle fairly complex problems with simple solutions. The dark side of Angular is it is easy to over engineer a solution if you go off the beaten path. Angular exposes a lot of the internals so it is tempting (and fun!) to muck around with it instead of going for the simple route.
Growing pains
I believe what you are dealing with is due to the growing pains Angular has had as it matured as project. A lot of side projects sprung up to fix the leaky holes that have since been plugged.
Rails and Angular, fast friends
So I am basing this off of how I have grown to use Rails with Angular. The examples are pulled from a pet project that is not going anywhere. Unfortunately, this is all in coffeescript, so hopefully that wont cause you problems. It is structured how I found works best with Rails, while keeping the spirit and fun of Angular.
* app/assets/javascripts
* app
* project_name_app.js.coffee.erb
* controllers
* controllers.js
* directives
* directives.js
* filters
* filters.js
* resources
* resources.js
* services
* services.js
Rails' asset pipeline wraps everything up using the application.js with the include:
//= require app/project_name_app
In the app/project_name_app.js.coffee.erb, it loads all of the directories with the includes
#= require_self
#= require app/controllers/controllers
#= require app/directives/directives
#= require app/filters/filters
#= require app/resources/resources
#= require app/services/services
Last, each of the sub directories js (controllers.js, directives.js, filters.js, resources.js, services.js) simply loads everything in that directory:
//= require_tree .
With this setup, the project_name_app.js.coffee.erb is loaded first, setting up Angular, the dependencies, and the app configuration. Then the controller, directives, filters, etc are loaded. One of the perks is new javascript added to a sub directory is automatically included thanks to the require_tree.
Keeping the $resource simple
The best $resources are RESTFUL. Meaning that it is the sample URL and the functionality changes based on the http method of the request. The downside is, if you have different URLs, you will probably need multiple resources. An example from the users_resource.js.coffee:
angular.module("DeployerApp.resources").factory "Users", ($resource) ->
$resource "/users.json", {},
index:
method: "GET"
isArray: true
type: "User"
angular.module("DeployerApp.resources").factory "User", ($resource) ->
$resource "/users/:user_id.json", {},
show:
method: "GET"
update:
method: "PUT"
angular.module("DeployerApp.resources").factory "CurrentUser", ($resource) ->
$resource "/users/current.json", {},
show:
method: "GET"
To get all users, you call Users.index(). To get a single user, you call User.show( user_id: 1 ). Last, a convenience $resource I that often use, to get the current authenticated user, CurrentUser.show().
Pretty straight forward and easy to read, avoiding have to have thick models. Each of the User $resources can be tested separately.
Angular is ready to do the work
You really only need to start mucking with $promise if you have some complicated juggling act when dealing with multiple responses. I have found it is simpler to just pass in the success and error callbacks to the $resource, for example:
CurrentUser.show success = (user) ->
$scope.currentUser = user
, error = (data,status) ->
# redirect to login
The variable names help make the code more readable, without them the coffeescript function definitions kind of blend together.
Simpler is always better
You do not need to worry about the $promise.then of the $resource, allowing you to tidying things up.

Related

Update view after AJAX call succeeds and returns data

I'm a beginner working on a recipe search app which returns a list of recipes based on the ingredients the user puts in the search bar. I'm learning to use Angular since it's convenient and makes my code more manageable.
So far I have succeeded in making jQuery Ajax GET requests to the API of my database and have a list of JSON objects returned.
Here's my Angular controller declaration:
var recipesData = []; // variable that will hold the returned data
angular
.module("awesomeapp")
.controller("listController", listController);
function listController () {
var vm = this;
vm.data = recipesData;
}
And I have stuff in vm.data displayed elsewhere in my view.
The problem is, when vm.data is set to recipesData, it doesn't contain anything yet because the page has just been loaded, the user hasn't put anything in and there isn't any data returned yet.
What should I do so that vm.data can be set after the Ajax call? Or can it be set outside of the listController function?
I'm looking for an elegant solution for this so that it makes everything easier to maintain. Thank you :)
The proper way to do this is to not use jQuery and use Angular's $http service to retrieve the data. The even more proper way to do this is to create your own service that internally uses Angular's $http service to get the data.
So first you would create the service. Something like this:
angular
.module("awesomeapp")
.service("recipeService", recipeService);
function recipeService($http) {
return $http.get(**url**)
}
Then your controller would look like something this:
function listController (recipeService) {
var vm = this;
recipeService.then(response) {
vm.data = response.data
}
}
You'll probably have more things on your service eventually, but that should get you going in the right direction. I'd highly recommend referring to John Papa's Angularjs style guide https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md for guidance on how to structure your app. You want to try to avoid using jQuery with Angular in general, but in particular, you want to avoid using it for things Angular does natively.

Mediate and share data between different modules

I am just trying to get my head around event driven JS, so please bear with me. There are different kinds of modules within my app. Some just encapsulate data, others manage a part of the DOM. Some modules depend on others, sometimes one module depends on the state of multiple other modules, but I don't want them to communicate directly or pass one module to the other just for easy access.
I tried to create the simplest scenario possible to illustrate my problem (the actual modules are much more complex of course):
I have a dataModule that just exposes some data:
var dataModule = { data: 3 };
There is a configModule that exposes modifiers for displaying that data:
var configModule = { factor: 2 };
Finally there is a displayModule that combines and renders the data from the two other modules:
var displayModule = {
display: function(data, factor) {
console.log(data * factor);
}
};
I also have a simple implementation of pub-sub, so I could just mediate between the modules like this:
pubsub.subscribe("init", function() {
displayModule.display(dataModule.data, configModule.factor);
});
pubsub.publish("init"); // output: 6
However this way I seem to end up with a mediator that has to know all of the module-instances explicitly - is there even a way to avoid that? Also I don't know how this would work if there are multiple instances of these modules. What is the best way to avoid global instance-variables? I guess my question is what would be the most flexible way to manage something like that? Am I on the right track, or is this completely wrong? Sorry for not being very precise with my question, I just need someone to push me in the right direction.
You are on the right track, I'll try to give you that extra push you're talking about:
It you want loose coupling, pub-sub is a good way to go.
But, you don't really need that "mediator", each module should ideally be autonomous and encapsulate its own logic.
This is done in the following way: each module depends on the pubsub service, subscribe to all relevant events and act upon them. Each module also publishes events which might be relevant to others (code samples in a minute, bear with me).
I think the bit you might be missing here is that modules, which use events, will hardly never be just plain models. They will have some logic in them and can also hold a model (which they update when receiving events).
So instead of a dataModule you are more likely to have a dataLoaderModule which will publish the data model (e.g. {data: 3}), once he finishes loading.
Another great requirement you set is sharing data while avoiding global instance-variables - this is a very important concept and also a step in the right direction. What you miss in your solution for this is - Dependency Injection or at least a module system which allows defining dependencies.
You see, having an event driven application doesn't necessarily mean that every piece of the code should communicate using events. An application configuration model or a utility service is definitely something I would inject (when using DI, like in Angular), require (when using AMD/CommonJS) or import (when using ES6 modules).
(i.e. rather then communicating with a utility using events).
In your example it's unclear whether configModule is a static app configuration or some knob I can tweak from the UI. If it's a static app config - I would inject it.
Now, let's see some examples:
Assuming the following:
Instead of a dataModule we have a dataLoaderModule
configModule is a static configuration model.
We are using AMD modules (and not ES6 modules, which I prefer), since I see you stuck to using only ES5 features (I see no classes or consts).
We would have:
data-loader.js (aka dataLoaderModule)
define(['pubsub'], function (pubsub) {
// ... load data using some logic...
// and publish it
pubsub.publish('data-loaded', {data: 3});
});
configuration.js (aka configModule)
define([], function () {
return {factor: 2};
});
display.js (aka displayModule)
define(['configuration', 'pubsub'], function (configuration, pubsub) {
var displayModule = {
display: function (data, factor) {
console.log(data * factor);
}
};
pubsub.subscribe('data-loaded', function (data) {
displayModule.display(data, configuration.factor);
});
});
That's it.
You will notice that we have no global variables here (not even pubsub), instead we are requiring (or injecting) our dependencies.
Here you might be asking: "and what if I meant for my config to change from the UI?", so let's see that too:
In this case, I rather rename configModule to settingsDisplayModule (following your naming convention).
Also, in a more realistic app, UI modules will usually hold a model, so let's do that too.
And lets also call them "views" instead of "displayModules", and we will have:
data-loader.js (aka dataLoaderModule)
define(['pubsub'], function (pubsub) {
// ... load data using some logic...
// and publish it
pubsub.publish('data-loaded', {data: 3});
});
settings-view.js (aka settingsDisplayModule, aka config)
define(['pubsub'], function (pubsub) {
var settingsModel = {factor: 2};
var settingsView = {
display: function () {
console.log(settingsModel);
// and when settings (aka config) changes due to user interaction,
// we publish the new settings ...
pubsub.publish('setting-changed', settingsModel);
}
};
});
data-view.js (aka displayModule)
define(['pubsub'], function (pubsub) {
var model = {
data: null,
factor: 0
};
var view = {
display: function () {
if (model.data && model.factor) {
console.log(model.data * model.factor);
} else {
// whatever you do/show when you don't have data
}
}
};
pubsub.subscribe('data-loaded', function (data) {
model.data = data;
view.display();
});
pubsub.subscribe('setting-changed', function (settings) {
model.factor = settings.factor;
view.display();
});
});
And that's it.
Hope it helps :)
If not - comment!
You do not need a mediator. Just import data, config, and display and call display(data, config) where you need to.
// import data
// import config
function render(){
display(data, config)
}

What is the best practice for using $resource and sharing the results across multiple controllers?

So, I've looked all over the place and can't find the answer I'm after.
I've recently learned a few new things and switched from having my services get and store shared data like this:
angular.module('myModule')
.service('stuffService', function(){
var thisService = {
stuff: {},
getSomething: function(){
var onSuccess = function(response){
thisService.stuff = response.data;
};
var onError = function(response){
alert('Doh!');
};
var promise = $http.get(<url>).then(onSuccess, onError);
return promise;
}
};
return thisService;
});
angular.module('myModule')
.controller('myController',function($scope, stuffService){
$scope.stuff = stuffService.stuff;
});
to this:
angular.module('myModule')
.factory('stuffService', function(){
var stuffResource = $resource(<stuff_url>, <params>, <etc>);
return {
stuff: stuffResource
}
});
angular.module('myModule')
.controller('myController', function($scope, stuffService){
$scope.stuff = stuffService.stuff.get(...);
});
This has been a really beneficial change in terms of most of the operation of my application; however, I'm running into a pickle as far as how would I share the data that the stuffResource returns.
Previously, I could just always reference stuffService.stuff from any controller that had stuffService injected into it. But now with $resource, I'm not sure how I would store this data. Using $scope.stuff or even $scope.stuff.get() would always run a query, and not act like an actual collection of "stuff".
At first, I tried to have a parent controller that did $scope.stuff = myService.stuff.get(...) and that actually worked really well... until I needed that same stuff outside of the parent controller. Now I need to figure out a way to store that data so that I'm not making the same API call over and over consecutively as the app loads up.
I've thought about turning on caching, which seems to be a pretty intuitive (duh!) approach but I'm not sure if that's the best course of action. Some data needs to be refreshed more often then others, so it would have to be caching with a cache limit of varying size/length and I'd be worried that some components would have different/newer data then components that loaded earlier. Maybe it feels like too simple of a solution, not sure. It would be nice if this was the answer, and I just used `stuffService.stuff.get()' just as if it was a stored object from the olden days.
I've also thought about using an interceptor to store this data similar to what my onSuccess method was doing previously. This seems ok too, but feels a little dirty/hacky. I would just need a little push to get this one working if I was on to a good idea.
My latest thought was to create a sort of "data service", that has the other services (like stuffService) injected into it. This "dataService" would have an object that it loads up with data from all these other services and then can be shared as dataService.data.stuff. This is nice in that my data can be a single source that's shared throughout the app, but it's also yet another service that needs to be injected because I'll probably still need other methods from stuffService. This could work better if I had one stuffService with nonCRUD methods for stuff, and another crudStuffService which was basically a wrapper for $resource. I'd really prefer to have anything that related to stuff under the same service. When I was doing that before, it was really helpful to have things abstracted out like stuffService.getStuff() to make http requests or stuffService.findStuffWithSpecialConditions() to do loops and conditions, etc. on stored/shared data.
So, anyone got any ideas on how to get and store data using $resource within the same service? Is this how it should be done? Am I missing something?
Thanks!
For what you are looking is – flyweight patterrn
The most important part of its implementations will be:
.factory('stuffService', function(){
var cache = {};
var stuffResource = function(<stuff_url>, <params>, <etc>) {
if(!cache[<stuff_url>+<params>+<etc>]) {
cache[<stuff_url>+<params>+<etc>] = $resource(<stuff_url>, <params>, <etc>);
}
return cache[<stuff_url>+<params>+<etc>];
}
return {
stuff: stuffResource
}
});

What is the AngularJS equivalent to Backbone's Collections?

Is there an equivalent to Backbone's Collection or Ext JS's Store in Angular JS? I'm learning about $resource, but not quite getting this aspect.
Controller
// This is the "collection" I'm interested in.
$scope.foos = [];
// Foo is a $resource.
Foo.query(function (foos) {
// This works, but is there a smarter "collection" object?
$scope.foos = foos;
});
$scope.createFoo = function (data) {
var foo = new Foo(data);
foo.$save(function (shinyNewFoo) {
$scope.foos.unshift(shinyNewFoo);
});
};
Explanation
In $scope.createFoo I'm making a new Foo, persisting it, then adding it to my poor man's collection, an array. This works and the view is updated correctly, but I'm too lazy for this. Ideally, I'd like to have a "collection" I can add to and remove from that will automatically POST/DELETE. Maybe something like the following.
Pretend Implementation
$scope.fooCollection = new CoolCollection({
// specify the type of resources this collection will contain
itemsResource: Foo
});
// Creates new Foo, saves, adds to collection.
$scope.fooCollection.add(data);
Does something like this exist? The $resource docs mention a collection, but I didn't really get it. This answer seemed promising, but didn't explain the collection idea. Am I missing something or just not thinking about this the Angular way?
Addendum
In the MEAN.io boilerplate, the article controller suggests that the "collection" is managed manually (see the splice below).
$scope.remove = function(article) {
if (article) {
article.$remove();
for (var i in $scope.articles) {
if ($scope.articles[i] === article) {
$scope.articles.splice(i, 1);
}
}
} else {
$scope.article.$remove();
$location.path('articles');
}
};
If this elusive "collection" existed, I suppose they would have used it. Instead, they're managing an array manually.
AngularJS does not define any kind of structured data model. This part is entirely up to you.
The $resource service is just a wrapper on top of the lower-level $http service; it defines a high level way to fetch your data from the server and has little to do with how you structure your data on the frontend.
If a more sophisticated frontend data model is required by your application, you should investigate other JS libraries or roll your own. However, angular's singleton services and powerful two-way data binding make this unnecessary for most small/medium applications.

AngularJS: Creating Objects that map to REST Resources (ORM-Style)

I'm pretty new to AngularJS, but I'm pretty unclear on how to tie it up to my Server's REST Api backend.
For example, say I have an "image" resource that I get by GET-ing: myApi/image/1/. This returns a json object with various fields. Let's say something like:
{url: "some/url", date_created: 1235845}
Now, I want some kind of representation in my AngularJS app of this "Image" object. This representation is more than just a mapping of the fields - I want to add "helper" functions, for example a function that converts the date_create field into something human-readable.
I know about the $resource service, but I'm unclear what I need to do to create a basic "class" in Angular, that uses Resource to get the JSON object, but then enhances it by adding various helper functions.
Bonus points:
I'm also unclear how to add "relationships" between models. For example, I might have a "user" resource that has embedded inside it an "image" resource, and I'll want to grab the User resource, but be able to call "Image" helper functions on the "Image" part of the model.
JSData
A project which started as angular-data is now "a framework-agnostic data store built for ease of use and peace of mind."
It is has excellent documentation and has support for relations, multiple backends (http, localStorage, firebase), validation and of course angular integration.
http://www.js-data.io/
BreezeJS
The AngularJS YouTube channel features this video using BreezeJS
Which is an advanced ORM which even supports client-side filtering and other cool stuff.
It best suited for backend that support OData, but can be made to work on other types of backends.
ngResource
Another option is to use the ngResource, here is an example on how to extend it with your own functions:
module.factory('Task', function ($resource) {
var Task = $resource(WEBROOT + 'api/tasks/:id', {id: '#id'}, {update: { method: 'PUT'}});
angular.extend(Task.prototype, {
anExampleMethod: function () {
return 4;
},
/**
* Backbone-style save() that inserts or updated the record based on the presence of an id.
*/
save: function (values) {
if (values) {
angular.extend(this, values);
}
if (this.id) {
return this.$update();
}
return this.$save();
}
});
return Task;
});
I found ngResource to be very limited, even compared to Backbone.Model which has:
Custom JSON parsing via Model.parse
Possible to extend a BaseModel (No the baseUrl in ngResource)
Other hooks like Backbone.sync, which enables LocalStorage, etc.
Restangular
"AngularJS service to handle Rest API Restful Resources properly and easily"
https://github.com/mgonto/restangular
Or try some of the other ORM's
https://stackoverflow.com/questions/6786307/which-javascript-orm-to-use
I'm creator of Restangular so my opinion can be biased.
But as Bob said, you can use Restangular for it.
Restangular uses your Restful API Resources to go over the tree. You can also add new methods to this.
This is coding example: https://github.com/mgonto/restangular#lets-code
And this way you can add new methods to your object (The bonus points :)) https://github.com/mgonto/restangular#creating-new-restangular-methods
Hope this works out for you :).
Otherwise, you can also use ngResource ($resource) for this but in my opinion, it needs some "love" and "sugar".
Bests
For simple interaction you can use Angular-Resource (http://docs.angularjs.org/api/ngResource.$resource) which can be quite handy for simple REST interaction (to download it go to http://code.angularjs.org/1.0.6/)
Sadly you only get limited control when using angular resource, and for anything more advanced you will need to create your own services based on Angularjs $http service - http://docs.angularjs.org/api/ng.$http.
Hope that helps.
After lots of research, here is a comprehensive list of all the solutions available:
Restmod
Modelizer
ModelCore
angular-watch-resource
angular-restful
ngResource
angularjs-rails-resource
angular-nested-resource
Aar.js
Angular Activerecord
Angular-Data
ngActiveResource
restangular
BreezeJS
ng-backbone
but honestly I wasn't very happy, so I decided to add to the list my own solution haha. Check it out here: $modelFactory.
Your end-result code ends up looking something like:
var module = angular.module('services.zoo', ['modelFactory']);
module.factory('AnimalModel', function($modelFactory){
return $modelFactory('api/zoo');
});
return module;
I believe this is a better solution over the rest because mainly the model definition closely resembles Angular's ngResource, adding just low-level features one needs that it lacks. Its super lightweight (1.45k gzip/min) and has only a few small dependencies ( no lodash, jquery, etc ).
ModelCore ( https://github.com/klederson/ModelCore ) works pretty much like this, and is very very easy to implement:
var ExampleApp = angular.module('ExampleApp', ['ModelCore']); //injecting ModelCore
ExampleApp.factory("Users",function(ModelCore) {
return ModelCore.instance({
$type : "Users", //Define the Object type
$pkField : "idUser", //Define the Object primary key
$settings : {
urls : {
base : "http://myapi.com/users/:idUser",
}
},
$myCustomMethod : function(info) { //yes you can create and apply your own custom methods
console.log(info);
}
});
});
//Controller
function MainCrtl($scope, Users) {
//Setup a model to example a $find() call
$scope.AllUsers = new Users();
//Get All Users from the API
$scope.AllUsers.$find();
//Setup a model to example a $get(id) call
$scope.OneUser = new Users();
//Hey look there are promisses =)
//Get the user with idUser 1 - look at $pkField
$scope.OneUser.$get(1).success(function() {
console.log("Done!",$scope.OneUser.$fetch());
});
Angular Rest-Mod is another good option for Angular-based Models / ORM.
Restmod creates objects that you can use from within Angular to interact with your RESTful API. It also supports collections, relations, lifecycle hooks, attribute renaming and much more.
One more example of helper for ngResource. This relies on fact that the vast majority of services is something like that:
http://host/api/posts
http://host/api/posts/123
http://host/api/posts/123/comments
http://host/api/posts/123/comments/456
So, the task is to make a helper that create AngularJS resource objects that maps on such services. Here it is:
'use strict';
var api = angular.module('api', ['ngResource']);
// RESTful API helper
api.addService = function (serviceNameComponents) {
var serviceName = "";
var resource = "/api"; // Root for REST services
var params = {};
serviceNameComponents.forEach(function (serviceNameComponent) {
serviceName += serviceNameComponent;
var lowerCaseServiceNameComponent = serviceNameComponent.toLowerCase();
var collection = lowerCaseServiceNameComponent + 's';
var id = lowerCaseServiceNameComponent + 'Id';
resource += "/" + collection + "/:" + id;
params[id] = '#' + id;
});
this.factory(serviceName, ['$resource',
function ($resource) {
return $resource(resource, {}, {
query: {
method: 'GET',
params: params,
isArray: true
},
save: {
method: 'POST',
},
update: {
method: 'PUT',
params: params,
},
remove: {
method: 'DELETE',
params: params,
}
}
);
}
]);
}
So, to use it simply call this helper
api.addService(["Post"]);
api.addService(["Post", "Comment"]);
And then you can use Post and PostComment in code with needed params like :post_id

Categories