Restangular Multiple IDs in GET - javascript

I'm looking at switching from resource to restangular in my AngularJS app. I like the new model, but I have one problem. I can't figure out how to make this API call:
http://localhost:8000/api/entity/groups/1,2,3,4/events
I have code like this:
var GroupService = ['Restangular', function (Restangular) {
var restAngular = Restangular.withConfig(function (Configurer) {
Configurer.setBaseUrl('/api/entity');
});
return {
getEvents: function (groupIds) {
return restAngular.all('groups', groupsIds).getList('events');
}
}
}];
Is there a way to ask for a set of groups (more than one and not all of them) and then get all events for any of those groups?

Use several method of Restangular
Restangular.several('accounts', 1234, 123, 12345).customGETLIST('events');
P.S.: I think this might be a bug of Restangular that .getList('events') is not working.

Related

Cannot access a collection in Angular-Meteor

I am trying to work with data from a Collection in Angular-Meteor, but so far I fail to access it.
In lib/collections.js I define the collection:
UserMeta = new Mongo.Collection('userMeta');
server/publish.js publishes it:
Meteor.publish('userMeta', function() {
return UserMeta.find();
});
and in my client code client/scripts/controllers/settings.controller.js I subscribe:
angular
.module('App')
.controller('SettingsCtrl', SettingsCtrl);
function SettingsCtrl($scope, $reactive) {
$reactive(this).attach($scope);
this.subscribe('userMeta');
//...
}
I have discovered that there seem to be multiple ways to subscribe (even used inconsistently in the official tutorial from Angular-Meteor), but I have decided to use the most recent syntax for v.1.3.2: Subscribe API
But if I want to view the whole content of the collection, it returns an empty array:
console.log(UserMeta.find().fetch()); // =[]
Or:
console.log(UserMeta.findOne()); // =undefined
However, if I run these commands in the client console in my browser, the expected results are returned.
Can somebody please give me a short example, how I can work with my collections? I am used to the way (pure) Meteor handles this and am confused that it does not seem to be as simple in Angular-Meteor.
Try using
Meteor.Methods
On your Server side call
Meteor.methods({
getUserMeta: function () {
var data = UserMeta.find({}).fetch();
return data;
}
All call this method on server side using
Meteor.call('getUserMeta',function (err, data) {
if (!err) {
Console.log(data);
} else {
console.log("error");
}
});
When you use Collection in console.log it isn't ready yet and hasn't any data.
You can use console.log inside helpers or you should check if collection is ready like this:
// Client-side
var subs = Meteor.subscribe('lastMsgRead', Meteor.userId());
Meteor.autorun(function() {
if (subs.ready()) { ... }
});

Lodash and AngularJS ngResource promise don't work well

I use lodash within my AngularJs app and it works well for local collections/arrays.
When I try to use it like so it doesn't work:
vm.colorsSizes = _.uniq(commonData.stock, 'colorName');
where commonData.stock is an array that resolves from an ngResource call.
angular
.module("common.services")
.factory("commonData",
["stockResource",
commonData]);
function commonData(stockResource) {
return {
stock: stockResource.query()
}
}
Why this happens and how can I fix it?
It sounds like you are trying to access it when it hasn't resolved yet and it's still empty. Give this a whirl:
commonData.stock.$promise.then(function () {
vm.colorSizes = _.uniq(commonData.stock, 'colorName');
});

service vs controller vs external js to put frequently used methods in angularjs

I have an angularjs app, which has several controllers with several viewes. When I started coding the app there were few methods(of similar kind), which were used in more than places, initially it looked OK to me to put those methods where ever needed (two or three controllers). But as my application grew I started noticing the code redundancy issue, as the method was required at more places.
Definitely this was my lack of experience which lead to this issue.
Now I decided to remove this redundant code from my app. I found the following options:
Service way: Remove the redundant code and put it in a new service and include the service all the places where I need the functionality.
External JS: Putting the redundant code in an external js file and just call the required method.
Leave the code as it is.
But here I want to mention that the redundant code I am talking is not very tight coupled and can be added and removed any where with a very little effort.
Now, what I want to know is from the above options, which one should I choose? OR are there much better options available for this issue(may be provided by angularJS itself).
Edit Basic examples of code:as I said
$scope.showSomething = function (show, ele) {
//show or hide the ele (element) based on value of show
}
You are using angular so surely you want to make your app structured according to MVC. what kind of MVC pattern your app will follow if your code is put anywhere in a js file like anything. I would recommend putting your code inside a service. that's the angular way of reducing redundancy. Also you have another option to set the function to the $rootscope here
I'm not sure about your case, but I had similar situation: I had a number of functions which provide validation functionality. I created service:
'use strict';
angular.module('myApp')
.factory('UtilService', ['Env', 'IBANChecker', function(Env, IBANChecker) {
var validateCallbacks = {
checkAddress: function (address) {
return address.action != 'delete';
},
validateIBAN: function (iban) {
return !iban || IBANChecker.isValid(iban);
},
.....
validateYCode: function(id) {
return YCodeChecker.isValid(id);
}
};
return {
/**
* Factory with callbacks for 'validate' directive.
* 0 arguments -- get all callbacks, over wise see #validateCallbacks object to get specific callbacks.
* if wrong callback name requested -> it will be ignored
* #returns {object} -- call requested callbacks.
*/
getValidateCallbacks : function() {
if(arguments.length) {
var result = {};
_.each(arguments, function(argument){
if(validateCallbacks[argument]) {
result[argument] = validateCallbacks[argument];
}
});
return result;
} else {
return validateCallbacks;
}
}
};
}]);
And code in controller looks like:
var validateCallbacks = UtilService.getValidateCallbacks('validateText', 'validateNumber');
_.each(validateCallbacks, function(callback, key) {
$scope[key] = callback;
});
I tend to use factories, specifically because factories can depend on other factories and logical modules can be defined. Consider the psuedo code below.
.controller('HisController', function (UtilityService) {
$scope.foo = UtilityService.foo;
})
.controller('HerController', function (UtilityService) {
$scope.foo = UtilityService.foo;
})
.factory('UtilityService', function (SomeOtherService) {
var service = {
foo: foo,
bar: bar,
}
return service
///////
function foo(a) {
return a.substring(0,1);
}
function bar(a) {
return SomeOtherService.doStuff(service.foo(a));
}
})

AngularJS learning about services and factories, a service in a factory?

I'm really trying to wrap my head around angular's service/factory/provider constructs before I refactor a pretty big project.
I've read lots of docs and articles on services vs. factories and thought I understood how each of them are created and what they do.
However, while trying stuff I attempted to use a service in a factory or two...
This was really useful: I now understand that there is only one of my 'jsonService' (it's a singleton), so this simple approach WILL NOT WORK... (I'll need each factory to have a separate instance of something)
.service('jsonService', ['$http', function ($http) {
var data= {'msg':'no data'};
this.serviceData= data;
this.get= function(url){
$http.get(url).then(function (resp) {
data= resp.data;
});
}
}])
.factory('fac1', ['jsonService', function(jsonService){
jsonService.get('json/data1.json');
return jsonService.serviceData;
}])
.factory('fac2', ['jsonService', function(jsonService){
jsonService.get('json/data2.json');
return jsonService;
}])
When I use the factories in a controller like:
myController.f1= fac1;
myController.f2= fac2.serviceData;
I can see that fac1 and fac2 both return the same object, they both have {msg:'no data'}, if I change one then they both change.
My question is:
Even though I can break on the service and see data= {msg:'no data'} and see it being set to the response data - why do I not see any change in fac1 or fac2 ?
All I can think is that somewhere there must be more than one var data, something is not a 'singleton' ????
EDIT: I have now tried:
this.serviceData= function(){return data;};
and:
myController.f2= fac2.serviceData(); // this is always the 'no data' object
myController.f3= fac2.serviceData;
if I then (a long time later) call:
var something= myController.f3();
then I do get the json data... but myController.f2 is still {msg:'no data'} why ?
Ok, after trying m.e.conroy's suggestion I finally figured it out...
The problem is nothing to do with angular, it's how javascript passes objects.
(see: Is JavaScript a pass-by-reference or pass-by-value language? )
The factories passed back a 'copy-reference' of the original {msg:'no data'} object, and when the service eventually assigned:
data= resp.data;
that replaced 'data', but the factory-supplied references persist as the old object.
Now, if I do:
.service('jsonService', ['$http', function ($http) {
var data= {'msg':'no data', 'result':null};
this.serviceData= data;
this.get= function(url){
$http.get(url).then(function (resp) {
data.result= resp.data; // update properties of the data object
data.msg='got data!'; // instead of replacing it
});
}
}])
...then everything makes sense!
The variables in myController are changed when data arrives (since I have not 'swapped out' the data object).
Obviously, I still have the problem that my two factories return the same object (I'll look at Sacho's suggestion on this) - but I think I've learned something pretty fundamental here.
Try this:
this.serviceData = function(){
return data;
};
Also you probably have a race situation. $http may not have returned by the time the application asks for the serviceData
The difference between angular's "services" and "factories" is miniscule - I suggest just using one or the other, and sticking with it. From this point out, I'll refer to these elements as "services", even though I exclusively use angular.factory to declare them.
For what you ultimately want to do, there is a much simpler solution - simply return the promise from your service.
this.get= function(url){
return $http.get(url)
}
Then in your controller/directive/whatever, just use it like:
jsonService.get(url).then(function success(response) {
// do things with the response
})
But you seem to want to use a service to create many instances, so here's a contrived example achieving that:
.factory('jsonService', jsonService)
jsonService.$inject = ['$http']
function jsonService($http) {
return Fixed
function Fixed(url) {
this.url = url
this.promise = null
this.get = get.bind(this)
function get() {
// This caches the request so you only do it once, for example
if (this.promise == null) {
this.promise = $http.get(url)
}
return this.promise
}
}
}
Then in your controller, you would do something like:
var fixedOne = new jsonService('fixedOne')
fixedOne.get().then(...)

$resource; how to encapsulate API methods

I have following angularjs service that exposes some methods to execute REST requests.
managerApp.factory('parameterService',
function($resource){
return {
findAll: $resource('rest/globalparam/list'),
getByName: $resource('rest/globalparam/getByName/?name=:name'),
update: $resource('rest/globalparam')
};
}
);
This is used as following:
$scope.parameters = parameterService.findAll.query();
$scope.selectedParameter = parameterService.getByName.get({name: $routeParams.id});
Although this works fine I'm not so happy about both the syntax and the fact that I need to know about the $resource API (query(), get()) in my controller. What I would like to see in my controller is:
$scope.parameters = parameterService.findAll();
$scope.selectedParameter = parameterService.getByName($routeParams.id);
This would make unit testing (mocking the service) a lot easier as well.
This is probably more a JavaScript than an AngularJS question.
Is this possible and how?
what you can do differently is to return functions from factory instead of a promise/resource object
managerApp.factory('parameterService',['$resource',
function($resource){
var findAll = function(){return $resource('rest/globalparam/list').query(); }
return {
findAll : findAll
};
}]
);

Categories

Resources