Angular JS: Get subproperty from service response - javascript

I am just starting out with Angular and trying to adapt a tutorial I have been following.
I have a resource defined as:
.factory('Session', function ($resource) {
return $resource('http://localhost/api/sessions');
});
I am trying to use the response with a controller like this:
.controller('SessionsCtrl', function($scope, Session) {
$scope.sessions = Session.query();
})
The problem I am coming up against is the format of the JSON response has the sessions in a subproperty as such:
{
sessions: [
{
id: 1,
title: "Welcome"
{
id: 2,
title: "Session 1"
}
]
}
How do I get the resource to look as the sessions property?

If your service is sending an object instead of an array, you should add isArray: false to its declaration:
yourApp.factory('Session', function ($resource) {
return $resource(
'http://localhost/api/sessions',
{},
{'query': {method: 'GET', isArray: false }}
);
});
In your controller you can use a callback:
yourApp.controller('SessionsCtrl', function($scope, Session) {
$scope.sessions = Session.query(function(result) {
return result.sessions;
});
});

Related

How to pass parameter inside Angular.js query service the proper way?

I'm trying to pass the folder name inside my query function.
In my controller, I have:
$scope.people = getResult.query({api: 'person'});
And in my services, I have, so far:
.factory('getResult', function($resource) {
var getResult = $resource('api/:path/:method/:id', {}, {
query: {method:'GET', params: {path:'#api', method:'get'}, isArray:true },
save: {method:'POST', params: {method:'save'} },
get: {method:'GET', params: {method:'edit'} },
remove: {method:'DELETE', params: {method:'remove'} }
});
return getResult;
});
The URL I'm getting is http://localhost/project/api/get?api=person but what I need is http://localhost/coral/api/person/get
I'm a newbie to Angular. What is the right way to do this, and why this is happening?
var getResult = $resource('api/:path/:method/:id',{path:'#api'}, {
query: {method:'GET', params: {method:'get'}, isArray:true },

Angularjs view not displaying data returned from factory

I set up a service that consumes a rails api that is returning json. The request comes back based on the console output as:
Resource {tests: Array[4], $promise: Promise, $resolved: true}
The problem I am having is nothing is displaying in my view. Do I need to convert the returned results somehow? When I ping that route via postman I get a json object as my result set.
I have the following set-up:
/service/test.js
angular.module('myApp')
.factory('Test', function($resource) {
return $resource('http://api.myapp-dev.com:3000/tests/:id', { id: '#_id' },
{
'index': {
method:'GET',
headers: {
'Authorization':'<a token>'
},
isArray: false
}
});
});
/controllers/tests.js
angular.module('myApp')
.controller('TestsCtrl', function ($scope, Test) {
$scope.tests = Test.index();
});
views/tests.html
<div>
<ul ng-repeat="test in tests">
<li>{{ test.value }}</li>
</ul>
</div>
You should do something like below in your controller.
Test.index(
function(response) {
$scope.tests = response.tests;
},
function(error) {
}
)
There are also other ways to do this like.
Test.index().$promise.then(
function(response) {
$scope.tests = response.tests;
},
errorCallback
)

Multiple parameters in AngularJS $resource GET

'use strict';
angular.module('rmaServices', ['ngResource'])
.factory('rmaService', ['$resource',
function ($resource) {
return $resource(
'/RMAServerMav/webresources/com.pako.entity.rma/:id',
{},
{
delete: { method: 'DELETE', params: {id: '#rmaId'}},
update: { method: 'PUT', params: {id: '#rmaId'}},
//RMAServerMav/webresources/com.pako.entity.rma/0/3
findRange:{method: 'GET', params:{id:'#rmaId'/'#rmaId'}}
});
}]);
RMAServerMav/webresources/com.pako.entity.rma/0/3
This is correct way to use findRange REST service. This one returns the rmaID from 1 to 4, but how can I use this from controller and what is the correct syntax in service?
In controller I would like to use it something like that:
$scope.rmas = rmaService.findRange({id:'0'/'3'});
but this is not working.
You can override url, Read $resource docs
url – {string} – action specific url override. The url templating is supported just like for the resource-level urls.
In resource declaration
findRange:{
url: '/RMAServerMav/webresources/com.pako.entity.rma/:id/:to',
method: 'GET',
params:{
id:'#id',
to: '#to'
}
}
In Controller
$scope.rmas = rmaService.findRange({id:0, to: 3});
I would prefer shorter way of defining parameters. Here is a complete example.
We have here 2 params :latitude and :longitude they defined only in the URL. Method get is already defined by ngResource
angular.module('myApp', ['ngResource'])
.controller('myCtrl', function (ReverseGeocoderResource) {
ReverseGeocoderResource.get({longitude: 30.34, latitude: 59.97}).$promise.then(function (data) {
console.log(data.address.road + ' ' + data.address.house_number);
})
})
.factory('ReverseGeocoderResource', function ($resource) {
return $resource('https://nominatim.openstreetmap.org/reverse?format=json&lat=:latitude&lon=:longitude&zoom=18&addressdetails=1&accept-language=ru');
});
Try changing your service using it in the controller like this:
'use strict';
angular.module('rmaServices', ['ngResource'])
.factory('rmaService', ['$resource',
function ($resource) {
var service ={}
service.rma = function(){ // name it whatever you want
return $resource(
'/RMAServerMav/webresources/com.pako.entity.rma/:id',
{},
{
delete: { method: 'DELETE', params: {id: '#rmaId'}},
update: { method: 'PUT', params: {id: '#rmaId'}},
//RMAServerMav/webresources/com.pako.entity.rma/0/3
findRange:{method: 'GET', params:{id:'#rmaId'/'#rmaId'}}
});
};
return service;
}]);
//in controller
rmaService.rma()
.then(function(resource){
$scope.rmas = resource.$findRange({id:'0'/'3'});
});
I have no idea if this will work BTW, because I have no use ngResource but that is how I code my factory services.

Angular wp-api cannot get headers for X_Total_Pages

I'm using Angular wp-api module and each time my $resource request responds I can see the ResponseHeaders in Chrome with X_Total_Pages and other header information. But I cannot add them to the scope.
Here is my controller...
.controller('newslettersController', ['$scope','$stateParams','$sce','WPFactory', function ($scope,$stateParams,$sce,WPFactory) {
$scope.newsletters = WPFactory.query({
param1: 'posts',
page: $scope.pageNum,
'filter[cat]': 8,
'filter[posts_per_page]' : 10,
'filter[orderby]': 'ID'
}, function(data, reponseHeaders) {
$scope.header = reponseHeaders('X_Total_Pages');
});
});
}]);
And my factory...
.factory("WPFactory", function($resource) {
var dataResponse = $resource('http://www.example.com/wp-json/:param1/:param2/:param3/:param4/:param6/:param7', {}, {
get: {
method: 'GET'
}
});
return dataResponse;
})
is this jeffsebrings angular module? If it is I think you need to inject your service with wpAPIResource:
.factory("WPFactory", function($resource, wpAPIResource)
and use it to query the json rest api (wp-api).
Also, not sure if your controller is passing the query object quite right:
I would change up your factory something like this:
.factory("WPFactory", function(wpAPIResource) {
var posts_query = function(args) {
return wpAPIResource.query(args);
};
return posts_query;
})

AngularJS second query not hitting service

I currently have a factory that looks like this:
ChecklistApp.factory('Api', ['$resource', function ($resource) {
return {
Checklists: $resource('api/checklists', {}, { 'query': { method: 'GET', isArray: false } }),
Checklist: $resource('api/checklist', {}, { 'query': { method: 'GET', isArray: false } }),
AddChecklist: $resource('api/addchecklist', {}, { 'query': { method: 'POST' } }),
UpdateChecklist: $resource('api/updatechecklist', {}, { 'query': { method: 'PUT' } })
};
}]);
I have two controllers that use this factory
a list controller - which lists all checklists
an update controller - which displays one checklist and allows its detailed to be modified
The list controller assigns the data to a variable which in turn is bound to the UI as follows:
$scope.search = function () {
Api.Checklists.query({ Name: $scope.searchName },
function (data) {
$scope.checklists = data.checklists;
}
);
};
In my edit controller I have the following update function which successfully updates the data in the DB and returns the user to the home (list) page.
var EditCtrl = function ($scope, $location, $routeParams, Api) {
$scope.action = "Update";
var id = $routeParams.editId.replace(/\D+/, '');
Api.Checklist.query({ id: id },
function (qd) { $scope.item = qd.checklist; }
);
$scope.update = function () {
Api.UpdateChecklist.save({ Id: $scope.item.id, Name: $scope.item.name },
function (data) {
$scope.item = data.checklist[0];
$scope.$apply();
$location.path('/#'); //Return to list controller
}
);
}
My issue is that after data is modified in my edit controller, I navigate back to the list control and although it hits the search query in the javascript it does not hit the service endpoint on the second call (skips it altogether) and the data is not refreshed (so the modified checklist has been updated on the DB but in the view on list control is remains as it was).
So my question is
How can I forcefully load the data again from the db using the same query that was run to load data initially ($scope.search in list control >> why does it skip this when the page is navigated to for the second time?) and/or alternatively is there a better way to just share the collection over multiple controllers (I read about nesting the scopes and putting the collection in the parent scope which could be accessed by both controllers but not sure if this is best practice or a suitable solution?)
Thanks

Categories