Fetching information from nested JSON based on unique fields using AngularJS - javascript

I have a json as following.
{
"id":14,
"discussion":8,
"parent":0,
"userid":2,
"subject":"communication skill discussion 2",
"message":"<p>hi all to communication discussion 2 </p>",
"children":[
24,
16,
15
]
},
{
"id":15,
"discussion":8,
"parent":14,
"userid":2,
"subject":"Re: communication skill discussion 2",
"message":"<p>hiiiiiiiiii</p>",
"children":[
25,
23
],
},
{
"id":23,
"discussion":8,
"parent":15,
"userid":2,
"created":1461562317,
"modified":1461562317,
"mailed":0,
"subject":"Re: communication skill discussion 2",
"message":"<p>helloooo</p>",
"children":[
],
}
I want first fetch the details whose Ids matches with the elments in children array
such as for id:14 there are 3 children 24,16,15.Then the control should go directly to id:15 and fetch details of id:15.Again id has children eg. consider id:23 which has no children and will directly print the message.
Please guide me how will I achieve this using ng-repeat of angular ?

Refer to the demo.
Please find the code below:
HTML:
<div ng-app="app" ng-controller="test">
<div ng-repeat="(key,value) in data">
{{key + 1}}) --
<span ng-if="value.children.length > 0">
{{value.children}}
</span>
<span ng-if="!(value.children.length > 0)">
No children found!!
</span>
</div>
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function($scope) {
$scope.data = [{
"id": 14,
"discussion": 8,
"parent": 0,
"userid": 2,
"subject": "communication skill discussion 2",
"message": "<p>hi all to communication discussion 2 </p>",
"children": [
24,
16,
15
]
}, {
"id": 15,
"discussion": 8,
"parent": 14,
"userid": 2,
"subject": "Re: communication skill discussion 2",
"message": "<p>hiiiiiiiiii</p>",
"children": [
25,
23
],
}, {
"id": 23,
"discussion": 8,
"parent": 15,
"userid": 2,
"created": 1461562317,
"modified": 1461562317,
"mailed": 0,
"subject": "Re: communication skill discussion 2",
"message": "<p>helloooo</p>",
"children": [
],
}];
});
UPDATE: As per the request
Demo
HTML:
<div ng-app="app" ng-controller="test">
<div ng-repeat="(key,value) in data">
[{{key + 1}}] --
<div ng-if="value.children.length > 0">
<div ng-repeat="item in value.children">
<span>{{item}}</span> <span class="green" ng-bind-html="getMessage(item)"></span>
</div>
</div>
<span ng-if="!(value.children.length > 0)">
No children found!!
</span>
<br />
</div>
</div>
JS:
$scope.getMessage = function(itemId) {
var flag = true;
var msg;
angular.forEach($scope.data, function(value, key) {
if (flag && value.id == itemId) {
flag = false;
msg = value.message;
}
});
return $sce.trustAsHtml(msg);
}
CSS:
.green {
color: green;
}

Use ng-repeat to display the records.
<ul ng:controller="Cntl">
<li ng:repeat="item in data">
{{item.subject}}: Parent
<ul>
<li ng:repeat="child in item.children">{{child}} : Children
</li>
</ul>
</li>
This is one of the way to display in html. Based on your page design ng-repeat will change.

You can use lodash or underscore _.where:
<div ng:controller="Cntl">
<div ng:repeat="item in data">
{{item.subject}}<br/>
Children
<div ng:repeat="child in item.children">{{_.where(data, {id:child});}}
</div>
</div>

First you need to restructure your json into a tree structure. May be you want to have a look at this post. Then you have to recursively add templates

Related

How to load different part of data from JSON file for each page using AngularJS?

I'm trying to create a shopping website using angularJs. My website has several html pages like women.html, men.html,...
I has 1 JSON file for the whole website. I want each website has different products, I did it but it only works on the main page (the page which showing all the products). When I click on a specific product, it doesn't show anything thing.
For more clearly, here is my code:
JSON file:
{
"Men": [
{
"name": "Adidas",
"price": 20,
"id": "adidas1",
"image": "pic4.png",
"description": "abcđsfadfdfsgsg"
},
{
"name": "Nike",
"price": 37,
"id": "nike1",
"image": "pic2.png",
"description": "abcđsfadfdfsgsg"
},
{
"name": "Converse",
"price": 25,
"id": "converse1",
"image": "pic3.png",
"description": "abcđsfadfdfsgsg"
}
],
"Women": [
{
"name": "Adidas2",
"price": 20,
"id": "adidas2",
"image": "pic6.png",
"description": "abcđsfadfdfsgsg"
},
{
"name": "Nike2",
"price": 37,
"id": "nike2",
"image": "pic7.png",
"description": "abcđsfadfdfsgsg"
},
{
"name": "Converse2",
"price": 25,
"id": "converse2",
"image": "pic5.png",
"description": "abcđsfadfdfsgsg"
}
]
}
Men.html:
<div ng-repeat="item in items.Men" style="float:left;">
<div><a href="#/item/{{item.name}}"><img src="/image/{{item.image}}" />
</a>
</div>
</div>
Women.html:
<div ng-repeat="item in items.Women" style="float:left;">
<div>
<a href="#/item/{{item.name}}"><img src="/image/{{item.image}}" />
</a>
</div>
</div>
App.js:
app.controller('ItemCtrl',
['$scope', '$routeParams', 'cartService',
function ($scope, $routeParams, cartService) {
$scope.item = {};
angular.forEach($scope.items, function (item) {
if (item.name == $routeParams.itemName) {
$scope.item.itemName = item.name;
$scope.item.itemPrice = item.price;
$scope.item.itemId = item.id;
$scope.item.itemImage = item.image;
$scope.item.itemDescription = item.description;
}
});
$scope.addProduct = function (item) {
cartService.addToCart(item, $scope.numberOfProducts);
};
}
]);
Product details page:
<div style="float:left; margin:0px 50px 300px 50px;">
<img src="/image/{{item.itemImage}}" style="margin- bottom:50px;margin-
left:200px;">
<p style="margin-right:0px;margin-top:50px;margin-left:50px;">Description:
{{item.itemDescription}}</p>
</div>
The code is really long so I only show its parts which I think making my code doesn't work.
Hopefully, there would be some help. Thanks in advance!
Check whether 'ItemCtrl' controller is binded to both men.html and women.html, if both the html files are not views.
Make two controllers and use $http method to call each page.Then using scope,reference data that you want and render in each page

How to toggle ng class by clicking a checkbox button?

Through webservice i used ngrepeat to show the check box.
It contains 10 check box. Check box was produced in div tag not used html input tag.
In Html,
<div ng-repeat="showproduct in showproducts.ProductList.products" class="col-md-3 mobile-two">
<div id="1" class="mSelected">{{showproduct.productName}}
</div>
In controller,
$http({
method : 'POST',
url : '///',
headers : {'Content-Type': 'application/x-www-form-urlencoded'},
data:$.param({
userId:$localStorage.loginUserDet.LoginStatus.user.userId,
sessionId:$localStorage.loginUserDet.LoginStatus.sessionId,
authToken:$localStorage.loginUserDet.LoginStatus.user.authToken
})
})
.success(function(data)
{
alert("success");
$scope.showproducts= data;
console.log($scope.showproducts);
});
JSon, to view the check box list
{
"ProductList": {
"code": 0,
"products": [
{
"productId": 1,
"productName": "Credit Card",
"productStatus": 1
},
{
"productId": 2,
"productName": "Net Banking",
"productStatus": 1
},
{
"productId": 3,
"productName": "Saving Account",
"productStatus": 1
},
{
"productId": 4,
"productName": "Loan",
"productStatus": 1
},
{
"productId": 5,
"productName": "Insurance",
"productStatus": 1
},
{
"productId": 6,
"productName": "Certificate Of Deposit",
"productStatus": 1
},
{
"productId": 7,
"productName": "Prepaid Card",
"productStatus": 1
},
{
"productId": 8,
"productName": "Investment",
"productStatus": 1
},
{
"productId": 9,
"productName": "All Products",
"productStatus": 1
},
{
"productId": 10,
"productName": "Demo",
"productStatus": 1
},
{
"productId": 11,
"productName": "Remittance",
"productStatus": 1
}
],
"uploadStatus": 1
}
}
I need to toggle the ngclass when i click the check obx.
Can anyone please help on this.
So, you want to div behave like toggle, on click you the selectTog() will be called and adds ClassName because of $scope.mSlected varibale will become true in the same way it removes the class
<div id="1" ng-class="(mSelected ? 'ClassName': '')" ng-click="selectTog()">{{showproduct.productName}}</div>
now in controller
$scope.mSelected = false; // setting it false by default
$scope.selectTog = function(){
$scope.mSelected = !$scope.mSelected;
}
What if there is ng-repeat?
remove ng-class from <div> and add class in the function.
<div ng-repeat="x in [1,2,3,4]"
<div id="x" ng-click="selectTog($event)">{{x}}</div>
</div>
now in controller
$scope.selectTog = function(){
$event.target.addClass("ClassName");
}
Do like this:
<div id="1" ng-class="'mSelected': data" ng-click="toggle()">{{showproduct.productName}}</div>
controller:
$scope.data = true;
$scope.toggle = function() {
$scope.data = !$scope.data;
}
When ever you click the div it will toggle the class.
All the best.
In your html:
<div id="1" class="mSelected" ng-click="myFunc($event)">{{showproduct.productName}}
</div>
In your controller:
$scope.myFunc = function(event) {
$(event.target).toggleClass("your_css_class");
}
ng-class evaluates an expression like ng-class="productSaleTrue ? onSale : notOnSale"
<div ng-class="mSelected" ng-click="mSelected = !mSelected">
{{showproduct.productName}}
</div>
This would evaluate to true and add the css class onSale to the element with that ng-class, if the expression would evaluate to false, the other css class notOnSale would be added to the element, in your case the checkbox.
There is a lot of documentation and codepen examples that you can take from! Have a nice day! A link, just for the sake of knowledge: https://appendto.com/2016/03/ng-class-use-cases-action/
A practical example taken from treehouse:
<div ng-controller="mainCtrl" class="list">
<div class="item" ng-class="{'editing-item': editing, 'edited': todo.edited}" ng-repeat="todo in todos">
<input ng-model="todo.completed" type="checkbox"/>
<label ng-hide="editing" ng-click="helloWorld()">
{{todo.name}}</label>
<input ng-change="todo.edited = true" ng-blur="editing = false;" ng-show="editing" ng-model="todo.name" class="editing-label" type="text"/>
<div class="actions">
Edit
Save
delete
</div>
</div>
{{todos}}
</div>

Reading JSON Response in AngularJS

I have an angular controller called productImages which returns following JSON data:
{
"Product_1":[
{ "image_id":"12469",
"name":"My Product 1 - Variety 1",
"url":"\/\/mystorefront.net\/120\/small\/1911791794.jpg"
},
{
"image_id":"12470",
"name":"My Product 1 - Variety 2",
"url":"\/\/drfuittf5cya9.cloudfront.net\/121\/small\/1911802897.jpg"
}
],
"Product_2":[
{ "image_id":"122349",
"name":"My Product 2 - Variety 1",
"url":"\/\/drfuittf5cya9.cloudfront.net\/122\/small\/1911791794.jpg"
},
{
"image_id":"123470",
"name":"191123897.jpg",
"name":"My Product 2 - Variety 2",
"url":"\/\/drfuittf5cya9.cloudfront.net\/123\/small\/1911802897.jpg"
}
]
}
In my angular code I have written:
<div ng-controller="productImages">
<div ng-repeat="product in products">
{{product.image_id}}
</div>
</div>
When I run this the ng-repeat div gets repeated twice but product.image_id does not show up. If I do {{product}} instead or {{product.image_id}} I get the whole JSON printed.
How do I print this JSON in angularJS? Also, How do I get Product_1, Product_2 printed?
Your object Product_1 seems to be an array which in turn has images.
I think you will need nested for loops to display the images
You try to repeat over the properties of an object.
Accourding to the documentation here you'll have to use
<div ng-repeat="(key, value) in myObj"> ... </div>
each property of your object is an array so I think that something like:
<div ng-repeat="(key, value) in myObj">
<div ng-repeat= "product in value">
{{product.image_id"}}
</div>
</div>
should do the trick
Use two loops for this as:
angular.module('app',[]).controller('mainCtrl', function($scope){
$scope.products = {
"Product_1":[
{ "image_id":"12469",
"name":"My Product 1 - Variety 1",
"url":"\/\/mystorefront.net\/120\/small\/1911791794.jpg"
},
{
"image_id":"12470",
"name":"My Product 1 - Variety 2",
"url":"\/\/drfuittf5cya9.cloudfront.net\/121\/small\/1911802897.jpg"
}
],
"Product_2":[
{ "image_id":"122349",
"name":"My Product 2 - Variety 1",
"url":"\/\/drfuittf5cya9.cloudfront.net\/122\/small\/1911791794.jpg"
},
{
"image_id":"123470",
"name":"191123897.jpg",
"name":"My Product 2 - Variety 2",
"url":"\/\/drfuittf5cya9.cloudfront.net\/123\/small\/1911802897.jpg"
}
]
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='mainCtrl'>
<div ng-repeat="product in products">
<div ng-repeat="item in product">
{{item.image_id}}
</div>
<hr/>
</div>
</div>
Your JSON syntax is incorrect. If I understand correctly, each of our product has several varieties. It should be as follows:
{
"Products": [
{
"Product": [
{
"image_id": "12469",
"name": "My Product 1 - Variety 1",
"url": "//mystorefront.net/120/small/1911791794.jpg"
},
{
"image_id": "12470",
"name": "My Product 1 - Variety 2",
"url": "//drfuittf5cya9.cloudfront.net/121/small/1911802897.jpg"
}
]
},
{
"Product": [
{
"image_id": "122349",
"name": "My Product 2 - Variety 1",
"url": "//drfuittf5cya9.cloudfront.net/122/small/1911791794.jpg"
},
{
"image_id": "123470",
"name": "My Product 2 - Variety 2",
"url": "//drfuittf5cya9.cloudfront.net/123/small/1911802897.jpg"
}
]
}
]
}
And you HTML should be:
<div ng-controller= "Products">
<div ng-repeat= "for oneproduct in Products">
<div ng-repeat="for variety in oneproduct">
{{variety.image_id"}}
</div>
</div>
</div>
Not tested this though...
You can't iterate on the object productImages because it's not an array.
You can iterate the objects "Product_1" and "Product_2".
If you want iterate the object productImage you have to write it ad an array.

Angular ng-repeat this JSON structure for user to user messaging

Very simple user to user messaging piece that I'm struggling with the interface in an app to use ng-repeat on the items.
Here is the data:
{
"ID": 4118,
"CreatedDate": "2015-08-20T03:12:50.397",
"recipient": [
{
"ID": 13,
"FirstName": "Heather",
"LastName": "Martin",
"ProfileImage": "https://../profilepictures/13"
}
],
"sender": [
{
"ID": 1046,
"FirstName": "Brad",
"LastName": "Martin",
"ProfileImage": "https://../profilepictures/1046"
}
],
"messages": [
{
"ID": 4137,
"ConversationID": 4118,
"UserID": 1046,
"Body": "hey",
"CreatedDate": "2015-08-20T14:34:42.4716233+00:00"
}
]
}
In the controller I get the conversations out of LS, one conversation is one record in LocalStorage, the JSON above will represent one conversation.
$scope.convo = JSON.parse(localStorage.getItem("convo-" + $stateParams.chatId));
Here is the structure I am trying to achieve (again, very simple, nothing fancy).
<ul>
<li class="item-avatar-left" ng-repeat="c in convo track by $index">
<img ng-src="{{c.recipient[0].ProfileImage}}" />
<p class="bubble speech">
{{c.messages[0].Body}}
</p>
</li>
</ul>
I've tried multiple variations on the ng-repeat directive.
Essentially what I'd like to achieve is just showing one <li> per each message.
Current result:
Console output of a conversation from LS:
You can try normally by ng-repeat
In controller like:
$scope.convo = [
{
"ID": 4118,
"CreatedDate": '2015-08-20T03:12:50.397',
//...... as your info
}
];
In HTML:
<ul>
<li class="item-avatar-left" ng-repeat="c in convo">
<img ng-src="{{c.recipient[0].ProfileImage}}" />
<p class="bubble speech" ng-repeat="m in c.messages">
{{m.Body}}
</p>
</li>
</ul>
NB: your $scope.convo need to be an array

Getting data from nested JSON object !!WITH ID'S!! using angular GET

Im kinda new to Angular/ JSON Objects and i'm trying to get something from a nested object.
That is not so hard, but the problem is that the JSON object has an that changes on the fly.
Below an example of 1 object from a complete list of JSON objects. As you can see this part of a larger object.
What i want is the task.assignment.name for each task in the ng-repeat, but i cant get to the assignment.name because of the integer that's between the assignment and name.
Look at my object:
{
"project-45": {
"label": "Bar",
"url": "http://someurl.com/api",
"assignments": {
"5147": {
"id": 5147,
"type": "Task",
"project_id": 45,
"assignee_id": 9,
"label_id": 27,
"category_id": 0,
"milestone_id": 0,
"name": "assignmentname",
"body": "<p>body.</p>",
"created_on": "2015-06-17 13:40:31",
"age": 6,
"created_by_id": 66,
"created_by_name": "Jelle",
"created_by_email": "jelle#example.com",
"due_on": "2015-06-19",
"priority": 0,
"task_id": 81,
"project": "Bar"
}
}
}
}
project-75": {
"label": "Another",
"url": "http://mijn.example.com/api",
"assignments": {
"5153":
...
This is my controller:
var main = angular.module("main", []);
main.controller("mainCntrl", function($scope, $http){
var apiUrl = "http://my.example.com/api.php?&format=json&";
var apiKey = "&auth_api_token=somekey";
var onUserComplete = function(response){
$scope.user = response.data;
console.log("User Data loaded");
}
var onTasksComplete = function(response){
$scope.tasks = response.data;
console.log("Tasks loaded");
}
$http.get(apiUrl + "path=my-tasks" + apiKey).then(onTasksComplete);
$http.get(apiUrl + "path=people/1/users/9" + apiKey).then(onUserComplete);
}
);
and finally the index.html file with the ng-reapter
<div class=" block full border">
<h3>Active tasks</h3>
<ul ng-repeat="task in tasks">
<li>
<ul>
<li>{{$index+1}}</li>
<li>Project: {{task.label}}</li>
<li>task name: {{task.assignments.name}}</li> <!-- Doesnt work -->
<li>task description: {{task.assignments.body}}</li> <!-- Doesnt work -->
</ul>
</li>
</ul>
</div>
Thanks!
<div class=" block full border">
<h3>Active tasks</h3>
<ul ng-repeat="task in tasks">
<li>
<ul ng-repeat="assignment in task.assignments">
<li>{{$index+1}}</li>
<li>Project: {{assignment.label}}</li>
<li>task name: {{assignment.name}}</li> <!-- Doesnt work -->
<li>task description: {{assignment.body}}</li> <!-- Doesnt work -->
</ul>
</li>
</ul>
</div>

Categories

Resources