Query parameters not taken into account in Restangular - angularjs

I am using Restangular on my front-end and I want to query this URL:
http://localhost:4000/study?projectId=123456
It returns a list of studies associated to a certain project. So I have the following controller code for the moment:
MyApp.controller('ProjectDetailCtrl', function ($scope, $routeParams, Restangular) {
// [...]
var resource = Restangular.all('study');
console.log($routeParams.projectId); // displays "123456", the current projectId
resource.getList('study', {projectId: $routeParams.projectId}).then(function(studies){
// Doing stuff
});
});
But it does not return the data I want. Indeed, when I look in the Network panel of Firefox, it queries http://localhost:4000/study, as if the parameter was not specified...
It seems to be the same code that the author give on Github, and every question on the web seems to use the same syntax. Why is my parameter ignored?

The first parameter of the getList should be your query params. You've already specified the study bit of your url. You had an extra "study".
var resource = Restangular.all('study');
resource.getList({ projectId: $routeParams.projectId }).then(function(studies) {
// do stuff
});

Related

Restangular data, getting into $scope for a list

Been wrestling with API stuff all day, and decided to use Restanglar. Really having issues getting the data out, and into $scope.
I understand that it won't just be the JSON that is returned from the API, and has a bunch of other internal methods etc. But when I get the data out, I can see it buried somewhere in the debugging with console.log, but I can't seem to get it into $scope to use it in my view which was working fine previously.
How can I get that data out into my $scope, and therefore my view?
Model
angular.module('horse', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setBaseUrl('http://url/api');
RestangularProvider.setResponseInterceptor(
function(data, operation, what) {
if (operation == 'getList') {
return data[what];
}
return data;
});
});
Controller
angular
.module('horse')
.controller("IndexController", function ($scope, Restangular) {
$scope.horse = null;
$scope.showSpinner = true;
Restangular.all('horse').getList().then(function(horse) {
$scope.horse = horse;
console.log($scope.horse);
});
});
API response
{"error":false,"horse":[{"id":"1","name":"horse 2"},{"id":"2","name":"horse 2"}]}
Edit 1
Restangular response
[Object, Object, route: "horse", getRestangularUrl: function, getRequestedUrl: function, addRestangularMethod: function, clone: function…]
Edit 2
I have also tried this - https://github.com/mgonto/restangular#using-values-directly-in-templates
$scope.horse = Restangular.all('horse').getList().$object;
Which just results in an empty array being output. I have also tried removing the setResponseInterceptor and modifying the structure of the api to result the data array directly without the meta stuff (error, etc), no joy :(
The data seems to be coming through. I notice you're using Steroids, have you checked the markup and not just the console?
Make sure you set the scope spinner to false, to ensure that the spinner is hidden when the data comes through.
$scope.ShowSpinner = false;
Assuming that what you have shown as "API response" is what's getting outputted from the console.log in your controller, it seems that all you need to do is set your scope model the the property "horse" in the response data like this:
$scope.horse = horse.horse;
Since that reads pretty oddly, you should change the param name of the .then callback to data, which would be a much more agnostic and standard param name. If you make that change you can set your horse data to your scope model from inside your callback like this:
$scope.horse = data.horse;
If I misunderstood your question let me know. Hope this is helpful.

how to make library of primary functions in AngularJS

I want to develop set of functions(sort of library) for CRUD in AngularJS so I can reuse them for couple of entities of my project. For server communication I made factory of $resource and using accordingly. $resource factory looks like this:
Model File:
var get_entity_model = angular.module("app.getentity", []).factory('getEntity', ['$resource', function($resource) {
return{
entity_view: $resource(baseurl+'/rest/'+serviceName+'/entity/:id/?app_name='+appName+'&fields=*', null, {'update': { method:'PUT' }})
}
}]);
And here how I'm using it in controller
Controller File:
getEntity.entity_view.get(
function(entity_list){
},
function(error){
}
)
Here entity_view is the table name. I'm passing all related functions like pagination and sub request to get the data of related tables etc code I put into success function of above request.
Now I want to make a library where I can define all this stuff and simply by calling the function I should be able to get all this stuff like:
entity.getEntity()
Should return same result as above code.
I tried with creating factory for above task but seems it need callback function and function at factory will return only data which I'm already getting from my model file so I need to make it compact and easy to use.
Factory Code at factory file:
var api = angular.module("app.entity_api", []).factory('entity_factory', ['$resource','getEntity',function($resource,getEntity) {
var entity_factory = {};
entity_factory.get_entity = function(callback){
getEntity.entity_view.get().$promise.then(
function(data){
callback(data.record);
}
);
}
return entity_factory;
}]);
And here how I call the function in controller:
Controller code:
api.controller("sample",['entity_factory','getEntity','$scope',function(entity_factory,getEntity,$scope){
$scope.init = function(){
entity_factory.get_entity(
function(data){
console.log(data);
}
);
}
$scope.init();
}])
Problem is that my entity_factory code will return only the data from server rest of the additional code I've to do in callback function which seems not much difference than my current exercise. So, the question is how can I achieve my goal to make a library of functions with additional code which return complete compiled result to make the code reusable for other entities and compact.
I like that you're a thinking of making a library but in this case, don't reinvent the wheel and save your precious time. Check out Restangular and your task will be a lot easier. Restangular is an AngularJS service that simplifies common GET, POST, DELETE, and UPDATE requests with a minimum of client code. It's a perfect fit for any WebApp that consumes data from a RESTful API.

Best practice to store and access data objects in Angular

I have a json endpoint that returns a list of objects. The first view is a list with just some basic info but if you select an item I want to show more details. Should I just construct and object in my factory and have another method to get the details? so
getItems() // returns list data
getItem(id)// goes through the object already retrieved and returns just the data?
I don't want to hit the server again for each item but I'm not sure of the best way to do this in Angular. It doesn't appear the Model is made for this in Angular.
Also, assuming Item has additional information that I may need to make another server request. What's the best way to store this locally so if I already fetches these details once I don't need to get it again?
If you want to exchange data between 2 controllers, you can use a provider
App.provider('Data', function() {
//Properties declaration
this.info = '';
//Setters
this.setInfo = function(info) {
this.info = info;
};
//Getters
this.getInfo = function() {
return this.info;
};
controller 1
App.controller(
'controller1',
['$scope', 'Data',
function($scope, Data) { Data.setInfo('here you put what you want') }]);
controller which get back information
App.controller(
'controller2',
['$scope', 'Data',
function($scope, Data) { Data.getInfo() }]);
More likely, you'll want to use either a factory or a service:
https://docs.angularjs.org/api/auto/service/$provide#factory
https://docs.angularjs.org/api/auto/service/$provide#service
In both cases, you provide a function which Angular will call once and store the return reference, then provide that reference to any controller or other Angular-managed object that requests it. The difference between a factory and service is that a service function is expected to be a constructor function (it's called using the "new" keyword) whereas a factory is a just invoked as a regular function.

Unable to get data from RESTfull API using AngularJS and $resource

I'm making a mobile app using ionic (based on the AngularJS framework) where I want to display data from a RESTfull API. I'm pretty new to AngularJS so I'm not familiar with the best practices. I want to get data from this API but with a weeknumber parameters in the URL so I can get data from specific weeks. I have looked especially to the example of the AngularJS website.
This is what I have in my services:
var eventServices = angular.module('starter.services', ['ngResource']);
eventServices.factory('EventServiceAPI',['$resource',
function($resource) {
return $resource('http://localhost:8080/schedulingAPI/plannedevents?weeknumber=:weeknumber', {}, {
query: { method: 'GET', params:{weeknumber:'weeknumber'}, isArray: true}
});
}]);
This is what I have in my controller to get the API data:
$scope.events = EventServiceAPI.get({weeknumber: 7});
However, I still keep getting the error:
Error: [$resource:badcfg] object
When I use the full API URL in services and $scope.events = EventServiceAPI.query() in my controller, the full API-data is displayed without error.
I also don't get where to put the parameters; in the brackets after the resource URL or the params option in the query method.
Edit:
The output of http://localhost:8080/schedulingAPI/plannedevents?weeknumber=:weeknumber
[{"id":2985,"event":{"eventId":589,"subject":"Masterproef","year":2014,"weekNumber":7,"dayNumber":6,"startHour":8,"startMinute":10,"endHour":12,"endMinute":45,"startTime":"2014-02-14T07:10:00Z","endTime":"2014-02-14T11:45:00Z","classgroups":[{"id":8,"name":"4ELICTI"},{"id":4,"name":"4ENAU"},{"id":10,"name":"4ELICTE"},{"id":1,"name":"4CHB"},{"id":3,"name":"4ENEL"},{"id":9,"name":"4EMEM"},{"id":2,"name":"4CHC"},[]],"teacher":null},"rooms":[{"id":24,"abbr":"D015"}]},{"id":4021,"event":{"eventId":604,"subject":"Bedrijfsbeleid 2 hc","year":2014,"weekNumber":7,"dayNumber":6,"startHour":8,"startMinute":10,"endHour":9,"endMinute":35,"startTime":"2014-02-14T07:10:00Z","endTime":"2014-02-14T08:35:00Z","classgroups":[{"id":6,"name":"4ELICT"},[]],"teacher":null},"rooms":[{"id":44,"abbr":"G120"}]}]
Replace params:{weeknumber:'weeknumber'} with params:{weeknumber:'#weeknumber'}, notice the #.
If the parameter value is prefixed with # then the value of that
parameter is extracted from the data object (useful for non-GET
operations).
From angular documentation
And call your function with query:
$scope.events = EventServiceAPI.query({weeknumber: 7});
Actually, you can simplify your resource declaration like this:
eventServices.factory('EventServiceAPI',['$resource',
function($resource) {
return $resource('http://localhost:8080/schedulingAPI/plannedevents');
});
}]);
Angular will automatically append the query string for you

AngularJS Execute function after a Service request ends

I am using AngularJS Services in my application to retrieve data from the backend, and I would like to make a loading mask, so the loading mask will start just before sending the request. but how can I know when the request ends?
For example I defined my servive as:
angular.module('myServices', ['ngResource'])
.factory('Clients', function ($resource) {
return $resource('getclients');
})
.factory('ClientsDetails', function ($resource) {
return $resource('getclient/:cltId');
})
So I use them in my controller as:
$scope.list = Clients.query();
and
$scope.datails = ClientsDetails.get({
date:$scope.selectedId
});
So the question would be, how to know when the query and get requests ends?
Edit:
As a side note in this question I've been using using angularjs 1.0.7
In AngularJS 1.2 automatic unwrapping of promises is no longer supported unless you turn on a special feature for it (and no telling for how long that will be available).
So that means if you write a line like this:
$scope.someVariable = $http.get("some url");
When you try to use someVariable in your view code (for example, "{{ someVariable }}") it won't work anymore. Instead attach functions to the promise you get back from the get() function like dawuut showed and perform your scope assignment within the success function:
$http.get("some url").then(function successFunction(result) {
$scope.someVariable = result;
console.log(result);
});
I know you probably have your $http.get() wrapped inside of a service or factory of some sort, but you've probably been passing the promise you got from using $http out of the functions on that wrapper so this applies just the same there.
My old blog post on AngularJS promises is fairly popular, it's just not yet updated with the info that you can't do direct assignment of promises to $scope anymore and expect it to work well for you: http://johnmunsch.com/2013/07/17/angularjs-services-and-promises/
You can use promises to manage it, something like :
Clients.query().then(function (res) {
// Content loaded
console.log(res);
}, function (err) {
// Error
console.log(err);
});
Another way (much robust and 'best practice') is to make Angular intercepting your requests automatically by using interceptor (see doc here : http://docs.angularjs.org/api/ng.$http).
This can help too : Showing Spinner GIF during $http request in angular
As left in a comment by Pointy I solved my problem giving a second parameter to the get function as following:
$scope.datails = ClientsDetails.get({
date:$scope.selectedId
}, function(){
// do my stuff here
});

Resources