$resource and get array - angularjs

I have an API which returns data with the following form (using tastypie):
{"meta":{
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 4},
"objects": [
{
"id": 1,
"name": "name1",
"resource_uri": "/api/v1/operator/1",
"short_name": "NA1"
},
{
"id": 2,
"name": "name2",
"resource_uri": "/api/v1/operator/2",
"short_name": "NA2"
},
...
]
}
So I thought that to have my resource working, I should have used:
var Operator = $resource('http://127.0.0.1:8080\:8080/api/v1/operator/:operatorId',
{operatorId:'#id'},
{
query: {
method: 'GET',
transformResponse: function (data) {
console.log(JSON.parse(data).objects)
return JSON.parse(data).objects;
},
isArray: true
}
});
But when I set isArray to true : I got the following error:
TypeError: Object #<g> has no method 'push'
If I set isArray to false, I have no error but my object also contains all meta datas for this request...
Not sure I understand correctly this $resource feature

Since $resource automatically converts the JSON string to object, you don't have to do call JSON.parse().
Just do
var Operator = $resource('http://127.0.0.1:8080\:8080/api/v1/operator/:operatorId', {
operatorId: '#id'
}, {
query: {
method: 'GET',
transformResponse: function (data) {
return data.meta.objects;
},
isArray: true
}
});

The json data you are sending is not an array, and the meta property is not something created by angular framework. If you are expecting that it gets deserialized into the objects array you have to return only that part and isArray would work.
For now what #sza mentions to get the array you override query and return data.meta.objects

Related

How do i modify a raw data object returned by an ExtJS AJAX proxy into a JSON object to be consumed by a Tree Store

In an effort to create a treepanel, i configure it with a treestore whose AJAX proxy url receives json data i have no control of. But using Ext.data.reader.Json's transform property invokable before readRecords executes, gives an option to modify the passed raw (deserialized) data object from the AJAX proxy into a modified or a completely new data object. The transform config, gives the code snippet below:
Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url : 'users.json',
reader: {
type: 'json',
transform: {
fn: function(data) {
// do some manipulation of the raw data object
return data;
},
scope: this
}
}
},
});
I would please like an example on how to go about modifying the return JSON object
[
{
"id": 3,
"attributes":
{},
"name": "user_one",
"login": "",
"email": "user_one#ats",
"phone": "0751223344",
"readonly": false,
"administrator": false,
"password": null
},
{
"id": 4,
"attributes":
{},
"name": "user_two",
"login": "",
"email": "user_two#ats",
"phone": "0751556677",
"readonly": false,
"administrator": false,
"password": null
}
]
into a JSON object fit for a treestore.
The hierarchical tree is to be rendered to show which user is under which admin using a condition administrator==true from the returned JSON, then a second AJAX request that returns that admin's users shown here.
[
{
"user_id": 3,
"admin_id": 1,
},
{
"user_id": 4,
"admin_id": 2,
}
]
Is the data nested at all? Otherwise why use a treepanel instead of a grid? To your question though, it'll depend on how you configure your treepanel but it would probably be something like this:
transform: {
fn: function(data) {
var treeRecords = Ext.Array.map(data, function(i){
return {
text: i.name,
leaf: true
//any other properties you want
}
});
var treeData = {
root: {
expanded: true,
children: treeRecords
}
};
return treeData;
},
scope: this
}

Read from json file angularjs

I had json file that I want to fetch data from it using angularjs 1.6 and I wrote some code in controller. I wanna sort out the properties names of objects in console like this:
['web-desktop','android','ios']
The problem that it returned array of undefined values and wanna to figure it out.
There is json file "data.json":
[
{
"platform": "web-desktop",
"cdn": 4.3673292887e+10,
"p2p": 5.667683381e+09,
"total": 4.9340976268e+10,
"upload": 5.774321084e+09,
"percentage": 12,
"viewers": 1,
"maxViewers": 10,
"averageViewers": 1.5725853094274147,
"trafficPercentage": 69.49888073943228,
"live": "unknown"
},
{
"platform": "android",
"cdn": 1.7035777808e+10,
"p2p": 1.526916976e+09,
"total": 1.8562694784e+10,
"upload": 2.753179184e+09,
"percentage": 9,
"viewers": 1,
"maxViewers": 12,
"averageViewers": 1.416065911431514,
"trafficPercentage": 26.14635154335973,
"live": "unknown"
},
{
"platform": "ios",
"cdn": 2.994960132e+09,
"p2p": 9.6722616e+07,
"total": 3.091682748e+09,
"upload": 3.3788984e+07,
"percentage": 4,
"viewers": 1,
"maxViewers": 3,
"averageViewers": 1.152542372881356,
"trafficPercentage": 4.354767717207995,
"live": "unknown"
}
]
And here is my controller:
'use strict';
var app= angular.module('app');
app.controller('MainController',['$scope', '$http', MainController]);
function MainController ($scope, $http) {
// REQUEST OPTIONS USING GET METHOD.
var request = {
method: 'get',
url: 'data.json',
dataType: 'json',
contentType: "application/json"
};
$scope.arrSeries = new Array;
$http(request)
.then(function onSuccess(jsonData) {
angular.forEach(jsonData, function (item) {
$scope.arrSeries.push(item.platform);
});
console.log($scope.arrSeries);
}).catch(function onError(request) {
console.log("not found");
});
}
It returns in console:
(6) [undefined, undefined, undefined, undefined, undefined, undefined]
Where is the trick?
You need to loop through items in jsonData.data not jsonData directly, like this:
$http(request)
.then(function onSuccess(jsonData) {
angular.forEach(jsonData.data, function (item) {
$scope.arrSeries.push(item.platform);
});
This is because jsonData is the response object that's returned, which looks like this:
response = {
config: {method: "GET", transformRequest: Array(1), transformResponse: Array(1), paramSerializer: ƒ, jsonpCallbackParam: "callback", …},
data: (3) [{…}, {…}, {…}],
headers: ƒ (d),
status: 200,
statusText: "OK",
xhrStatus: "complete"
}
So if you loop on the response directly, you'll loop 6 time trying to get platform from each item (which isn't there). Hence the result you got.
The data that your request returns sits in response.data
response = {
...
data: (3) [{…}, {…}, {…}],
...
}
Hope that helps.

angularjs undefined resource

I am new in angularJs, I am trying to have my first steps in developping an application and I am facing a problem.
I am calling an external resource that return an object json via $resource.get(), in the callBack I am getting the correct values, but in the service the values are undefined, the problem is when I am printing the resource in the console the result has the correct values.
my json object :
{
"readOnly": false,
"questions": [
{
"questionId": "0",
"questionTitle": "question0",
"isMondatory": true,
"responseList": [
{
"questionId": "0",
"questionTitle": null,
"responseId": "00",
"responseTitle": "response00"
},
{
"questionId": "0",
"questionTitle": null,
"responseId": "01",
"responseTitle": "response01"
},
{
"questionId": "0",
"questionTitle": null,
"responseId": "02",
"responseTitle": "response02"
},
{
"questionId": "0",
"questionTitle": null,
"responseId": "03",
"responseTitle": "response03"
}
]
},
{
"questionId": "1",
"questionTitle": "question1",
"isMondatory": true,
"responseList": [
{
"questionId": "1",
"questionTitle": null,
"responseId": "10",
"responseTitle": "response10"
},
{
"questionId": "1",
"questionTitle": null,
"responseId": "11",
"responseTitle": "response11"
},
{
"questionId": "1",
"questionTitle": null,
"responseId": "12",
"responseTitle": "response12"
},
{
"questionId": "1",
"questionTitle": null,
"responseId": "13",
"responseTitle": "response13"
}
]
}
my controller is
app.controller('mycontroller', function ($scope,myservice) {
$scope.infos = null;
$scope.infos = myservice.getInfo();
}
my service is :
angular.module('xxxx').factory('myservice', function($window,$resource,$routeParams,$http,apicallservice) {
// Public API here
return {
getInfo : function(){
var result=null;
var url = "myUrl";
result = apicallservice.GetApiCall(url,$routeParams);
console.log(result.readOnly); // print undefined => KO
return result;
},
//.... other functions
my apicallservice :
angular.module('xxxx')
.factory('apicallservice', function ($http,$resource) {
var result;
// Public API here
return {
GetApiCall: function (url,obj) {
// resource
var resource = $resource(url,{param1:obj});
// cal the api
result = resource.get(function(callBack) {
console.log(callBack.readOnly); => print false => OK
return callBack;
}, function(error) {
console.log(error);
return error;
});
return result;
},
PostApiCall : function(url,obj){
result = $http.post(url,obj).then(
function (response) {
console.log(response);
}, function (error) {
console.log(error);
});
}
};
});
please can you help me ?
thanks in advance.
From angularjs api documentation for $resource
It is important to realize that invoking a $resource object method
immediately returns an empty reference (object or array depending on
isArray). Once the data is returned from the server the existing
reference is populated with the actual data. This is a useful trick
since usually the resource is assigned to a model which is then
rendered by the view. Having an empty object results in no rendering,
once the data arrives from the server then the object is populated
with the data and the view automatically re-renders itself showing the
new data. This means that in most cases one never has to write a
callback function for the action methods.
So basically for
$scope.infos = myservice.getInfo();,
result will have an empty object/array reference. Since the call is asynchronous, the next line(console.log(result.readOnly)) gets called immediately and you will get undefined. Only when the underlying get/post call actually completes, variable result will be populated with the value from the server
I found what was going wrong, in the controller I had to add then() :
instead of this :
app.controller('mycontroller', function ($scope,myservice) {
$scope.infos = null;
$scope.infos = myservice.getInfo();
}
do this :
app.controller('mycontroller', function ($scope,myservice) {
$scope.infos = null;
myservice.getInfo().then(function(data) {
$scope.infos = data;
});
}
this resolved the problem.

ngResource return a singular item

When trying to return a singular item from a mongoDB I keep getting an error telling me I am returning an array as apposed to an object. Here's my service code:
resource: $resource('http://localhost:8080/api/item/:itemId', null, {'get' : {method: 'GET'}}, {stripTrailingSlashes: false})
function getItem(itemId) {
return this.resource.get({itemId: itemId}).$promise.then(function(resource){
return resource;
});
}
The service is above is called resolve like so:
.state('cocktail', {
templateUrl: 'client/app/features/item/item/item.html',
controller: 'ItemController',
controllerAs: 'vm',
data:{
title: 'Item'
},
params:{
itemId: null
},
resolve:{
item: getItem
}
function getItem($stateParams, itemService) {
return itemService.getItem($stateParams.itemId);
}
Then in my controller:
ItemController.$inject = ['itemService', 'item'];
function ItemController(itemService, item) {
var vm = this;
vm.item = item;
}
The object that is returned in the call is:
[
{
"_id": "57586f25661d33fe21057866",
"name": "Red Velvet",
"description": "Red Velvet Description here",
"image": "red-velvet",
"__v": 0,
"gred": []
},{
"_id": "57586f25661d33fe21057884",
"name": "Red Item",
"description": "Red Velvet Item here",
"image": "red-velvet-item",
"__v": 0,
"gred": []
},
]
The error I get in my console is - [$resource:badcfg] Error in resource configuration for action get. Expected response to contain an object but got an array. I am not expecting an array but the object of the ID I pass through in the resolve. If anyone has any comments or can see what I'm doing wrong please let me know! This is bugging me and I know it's going to be a simple fix haha!

How to post an array object in ajax call in angularjs

I have below JSON response, I have to post that in my ajax call but i don't know how to do that.
JSON response:
{
"iASensorTypePresetRequest": [{
"sensorPresetTypeId": "1",
"min": "30",
"max": "50"
}, {
"sensorPresetTypeId": "3",
"min": "1",
"max": "200"
}, {
"sensorPresetTypeId": "5",
"min": "true",
"max": "NA"
}, {
"sensorPresetTypeId": "6",
"min": "false",
"max": "NA"
}
]
}
I have below code:
var formData = $scope.PresetObject;
var reqHeader = {
method: 'POST',
url: getAPI_URL('221') + $scope.selectedUseCase,
data: formData
};
ajaxService.AjaxCall(SuccessFunction, ErrorFunction, reqHeader);
I have posted objects but i have to post that in array that is 'iASensorTypePresetRequest'
I have written service 'ajaxService' and written functions in it 'SuccessFunction' in success function i have called $http service also I have written error function and calling 'AjaxCall' function of service from controller.
My question is How to post an array containing objects in ajax call?
I use the $http service when communicating with the backend. I recommend placing all your backend connectivity into a service. I call mine datacontext.
this is the link to the $http documentation
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
$http(req).then(function(){...}, function(){...});
If your api is RESTful you can use the $resource factory.

Resources