I have read through numerous questions here already, but something just isnt clicking with me and understanding this issue i have.
the js code:
app.controller('example_ctrl',['$scope','$http', function($scope,
$http){
$http.get('api_call_here').then(function successCallBack(response){
$scope.response = response;
});
Json format of api:
{
"categoryOne": {
"1": {
"title": "someData1",
"description": "This is number One"
},
"2": {
"title": "moreData1",
"description": "I am not a number, I'm a free man!"
}
}
}
Now because this hasnt been returned in an array, I get an error whenever I try to filter it. As an example:
<div ng-repeat="(category, object) in response.data">
<div ng-repeat="item in object">
<p>{{item.title}}</p>
</div>
</div>
Now if i try to put an ng-model on a search input, and tie that to the ng-repeat with a |filter:ng-model name, I get an error.
What I basically WANT to do, is when you type text into the search field, have it return only the title/descriptions that contain that text.
You can transform the list of object in each category to array:
app.controller('example_ctrl',['$scope','$http', function($scope, $http){
$http.get('api_call_here').then(function(response) {
Object.keys(response.data).forEach(function(category) {
response.data[category] = Object.values(response.data[category]); // Transfom list of objects in each category to array
});
console.log("transformed: ", response);
$scope.response = response;
});
Related
iam newbie and i want to ask.
i want to get some value from JSON API (title, course_id, etc), and put the Value to my Template with Directive. so at Index, i can repeat my tempalate with data from the API.
How to get Value from that JSON ?
This my Code :
my API
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url": "http://192.168.1.37:8000/api/courses/a/",
"title": "I Love You", <-- I want to put this Value to my Template
"course_id": "1",
"starting_date": "2016-10-03"
}
]
}
Controller demo.js
demo.controller("demo", function($scope, $http) {
$http.get('http://192.168.1.37:8000/api/courses/'). <-- Data From my API
then(function(response) {
$scope.courses = response.data;
});
});
demo.directive("demoItemDirective", function() {
return {
scope : { demoInfo : "=info"},
templateUrl : "/app/demo.tmpl" <-- My Template
};
});
My Template demo.tmpl
<p>{{demoInfo.count}}</p> <-- Works, count Displayed
<p>{{demoInfo.results.title}</p> <-- Not works, title not displayed
My Index.html
<div ng-repeat="group in courses | groupCount:2">
<div ng-repeat="x in group">
<demo-item-directive info="x"></demo-item-directive>
</div>
</div>
It should be
<p>{{demoInfo.results[0].title}</p>
Your result contain an Array of object.
You need to access with index.
According to your post, the result is an array:
"results": [
{
"url": "http://192.168.1.37:8000/api/courses/a/",
"title": "I Love You", <-- I want to put this Value to my Template
"course_id": "1",
"starting_date": "2016-10-03"
}
]
Thus, you can't refer to the title itself, you have to reference the first element:
{{demoInfo.results[0].title}}
I am working with angularjs. I had some different kind of issue.
I have HTTP call. after HTTP request the response will be stored in two different variable. after I change data in variable means it will change automatically into other variable also.
$http.get('get/list')
.success(function(data, status) {
$scope.test1 = data;
$scope.test2 = data;
})
.error(function(data) {
});
//sample json
{
"lists": [
{
"_id": "575e6d4bde006e3176bb9dc5",
"items": [
{
"name": "a"
}, {
"name": "b"
}
],
"name": "fridge",
"status": "done"
}
]
}
After I will push json into test1 variable.
$scope.addRow = function(comment1) {
$scope.test1.lists.push({
'name' : 'c'
});
};
But When I print the $scope.test2 it added automatically new added items also. (name = c).
Any Idea to fix this problem. I need to print test2 what getting in HTTP request.
That happened because $scope.test1 & $scope.test2 both are referring to same object in memory. Use angular.copy to create deep copy of object. So, $scope.test1 & $scope.test2 will no longer be alias of each other
$http.get('get/list')
.success(function(data, status) {
$scope.test1 = angular.copy(data);
$scope.test2 = angular.copy(data);
})
.error(function(data) {
});
Its the same relation of shallow copy / deep copy.
When you are storing values in $scope.data1 and $scope.data2, you have to make a deep copy.
Use something like this.
$scope.test1 = angular.copy(data);
$scope.test2 = angular.copy(data);
It will create a deep copy instead and changing in $scope.data1 won't effect $scope.data2
On the HTML side, you can also cut the data binding between the view and the controller by putting two ':' as a prefix of the variable. Like this :
<div>{{::test2}}</div>
It's not really like your variable won't be updated again, but the changes will not be displayed into the web page.
I know this question already exists on SO (as here : Error in resource configuration. Expected response to contain an object but got an array ) and even if I've already faced this error a few days ago, I didn't find why I'm getting it now.
On the one hand, I have a RESTful API in Node Express. It gives me access to a database, where I'm trying to get some data. When using a specific $resourcerequest, I'm getting this JSON (tested with Postman) :
[
{
"ref": 2,
"type": "string here",
"matriculeMD": 4567,
"name": "William",
"date": "2016-09-14T22:00:00.000Z",
"client": 1
},
{
"ref": 4,
"type": "string here",
"matriculeMD": 1589,
"name": "Averell",
"date": "0000-00-00",
"client": 1
}
]
On the other hand, I have an Angular JS app. This one use a factory to get the data from the API :
.factory('Things', ['$resource', function($resource) {
return $resource(
'api_url/:client_id',
{client_id: '#client_id'}, // getting some data from an ID
{'query' : {
method : 'GET', // ofc, it's a get request in the API
isArray : false // to be sure to get an object and not an array
}
}
I also have a controller which uses this factory, trying to execute the query with the param :
app.controller('ctrl', ['$scope','Things', function ($scope,$things)
{
$scope.thing = $things.query({},{'client_id':'1'});
// replacing '#client_id' from factory with 1. I also tried with quoteless 1.
}
]);
And, finally, I have an html view, where I try to use the data I'm supposed to get in $scope.thing with some <div ng-repeat'thing in things'>{{thing.ref}}</div>.
By reading other posts, I was sure that adding an isArray : false to the factory would fix the problem, as it has already fixed it in another factory.
Any idea ?
Edit : Thanks for your replies. I changed my factory code with :
.factory('Things', ['$resource', function($resource) {
return $resource(
'api_url/:client_id',
{client_id: '#client_id'}, // getting some data from an ID
{'query' : {
method : 'GET', // ofc, it's a get request in the API
isArray : true //
}
}
And it fixed the error. Now, I'm working on another problem with my $scope content which is undefined and send $promise : Promise, $resolved : Resolved. I read $resource doc to understand what it means, but I still have no idea of how to make it work.
As doldt said before, you are actually expecting an array.
Your response is an array of objects.
Either you change isArray to true or you change the response on the server to return an object.
Once you have this changed, you can use your resource on the controller this way (providing a callback for the $resource, since you are now dealing with promises) :
$things.query( {}, { 'client_id' : '1' }, function( response ){
$scope.thing = response;
});
I think you are doing wrong with isArray flag. It must be true if you are sending array.
Try it....
// Code goes here
var myApp = angular.module('myApp', ['ngResource']);
myApp.factory('Things', ['$resource',
function($resource) {
return $resource(
'data/sample.json'
//, {
// client_id: '#client_id'
//}, // getting some data from an ID
//{
// 'query': {
// method: 'GET', // ofc, it's a get request in the API
// isArray: true // to be sure to get an object and not an array
// }
//})
)
}
]);
myApp.controller('myCtrl', function($scope, Things) {
Things.query({}, {
'client_id': '1'
}).$promise.then(function(data) {
$scope.thing = data;
console.log($scope.thing);
})
});
[
{
"ref": 2,
"type": "string here",
"matriculeMD": 4567,
"name": "William",
"date": "2016-09-14T22:00:00.000Z",
"client": 1
},
{
"ref": 4,
"type": "string here",
"matriculeMD": 1589,
"name": "Averell",
"date": "0000-00-00",
"client": 1
}
]
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script data-require="angular.js#*" data-semver="2.0.0-alpha.26" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-resource.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="myCtrl">
<h1>{{1/2}}</h1>
<ul ng-repeat="t in thing">
<li>{{t.name}}</li>
</ul>
</body>
</html>
--output
0.5
William
Averell
Try:
$things.query({},{'client_id':'1'}).$promise.then(function(result){
$scope.thing = result;
console.log($scope.thing);
});
I have quite an interesting question (I hope) for all you AngularJS gurus out there. I am looking to create a dynamic list of form input fields based on a SELECT dropdown. As an example, we have a number of categories with each category having a set of specifications which are unique to that category. To help with the explanation we have the following:
Firstly, in the controller we start by initializing the models.
$scope.category = {};
$scope.category.specs = [];
Next we ready the data to be used in the form (actually retrieved from the server via $http). We also initialize a variable to the first element in the categories array.
$scope.categories = [
{ "id": "1", "name": "mobile", specs: [
{ "id": "1", "label": "Operating System" },
{ "id": "2", "label": "Camera type" } ] },
{ "id": "2", "name": "laptop", specs: [
{ "id": "1", "label": "Operating System" },
{ "id": "2", "label": "Graphics Card" } ] }
};
$scope.selectedCategory = $scope.categories[0];
In the form, we have a dropdown which when selected loads the appropriate input fields specific to that category. We use the ngRepeat directive to accomplish this. This is a dynamic list of fields based on $scope.categories.specs. (please note the ???)
<select ng-model="selectedCategory" ng-options="category.name for category in categories"></select>
<div ng-repeat="spec in selectedCategory.specs">
<label>{{spec.label}}</label>
<input type="text" ng-model="???">
</div>
Ultimately, when the user clicks the submit button, we would like to extract the category he/she has selected and then package it together with the specifications they have filled in. The post request should contain something like the following for instance (of course, I only included one spec item, but in reality there would be many):
{ "id": "1", specs [ { "id": "2", "details": "RADEON HD 8970M" } ] }
Unfortunately I am not really sure how to accomplish this. I need to somehow create an array for the spec model, and then ensure that both the ID and user entered data are appropriately extracted... what goes in the ??? and what do we do after? Any help would be much appreciated.
this is how I do it. I make a form, validate it with angular, and then when its valid I submit it with a function.
<form name="signup_form" novalidate ng-submit="signupForm()"></form>
$scope.signupForm = function() {
var data = $scope.signup;
$http({
method : 'POST',
url : 'http://yoursite.com/mail.php',
data : $.param(data), // pass in data as strings
headers : { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload)
})
.success(function(data) {
});
}
also if you want to look at another form validation system for angular check out http://nimbly.github.io/angular-formly/#!/ It may help you solve your current form system.
In the controller, initialize $scope.specDetails as follows:
$scope.specDetails = {};
angular.forEach($scope.categories, function (category, index1) {
$scope.specDetails[category.id] = {};
angular.forEach(category.specs, function (spec, index2) {
$scope.specDetails[category.id][spec.id] = '';
});
});
In the html, replace "???" with specDetails[selectedCategory.id][spec.id]
In my model I have a complext object graph and would like for angular to build branches as the user inputs data. This does work as long as the property path does not contain an array. Is there a way to get angular to create the array and add an item to it when it?
demo controller
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.deal ={};
});
This works
<input type="text" ng-model="deal.BorrowerSet.0.Borrower.Name" />
and produces an object
{
"BorrowerSet": {
"0": {
"Borrower": {
"Name": "Bob"
}
}
}
}
However when an array is used this does not work.
<input type="text" ng-model="deal.BorrowerSet[0].Borrower.Name" />
I would like the following result
{
"BorrowerSet": [
{
"Borrower": {
"Name": "Bob"
}
}
]
}
and I would like angular to build the object graph the same way it does for
http://plnkr.co/KiwjyG