Augmenting JSON from REST about additional data within AngularJS - angularjs

EDIT (SOLUTION): http://plnkr.co/edit/SjzpmQqMPuOCvcdZn5bV?p=preview
I get following data from a REST-API:
[
{
"a": "foo"
},
{
"a": "bar"
}
]
but need that:
[
{
"a": "foo",
"activated": false
},
{
"a": "bar",
"activated": true
}
]
how could I do that within angular, how can I principally add some new properties so that I can react on their change may be with a new style.
SECOND QUESTION: Or maybe I need following transformation:
{
"a": {
"foo": true,
"bar": false
}
}
Is there an "Angular-way" to do that? Do I have to use libraries like lodash, underscore etc.. ?

You can use underscorejs's extend method.
http://jsfiddle.net/2676saju/
<!doctype html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
</head>
<body>
<div ng-controller="MyController as vm">
{{vm.list | json}}
</div>
<script>
angular.module('app', [])
.controller('MyController', function () {
var vm = this;
var list = [{
"a": "foo"
}, {
"a": "bar"
}];
vm.list = _.each(list, function (item) {
var result = _.random(0, 100) % 2 ? true : false;
_.extend(item, { activated: result });
});
});
</script>
</body>
</html>
Result
[ { "a": "foo", "activated": false }, { "a": "bar", "activated": true } ]

array[1].c = "Michael Jackson";
array[1].d = ["Thriller..."]
and array[0].c for george michael...

For an "Angular way" solution, you can use the angular.forEach function
angular.module("myApp")
.controller("myVm", function($scope) {
var vm = $scope;
vm.items = [
{
"a": "foo"
},
{
"a": "bar"
}
];
vm.activeList = [];
var pushItem = function(value,key) {
var o = {};
o[value.a] = false;
this.push(o);
};
angular.forEach(vm.items, pushItem, vm.activeList);
});
OUTPUT
activeList = [{"foo":false},{"bar":false}]
For more information on the angular.forEach function, see the AngularJS angular.forEach API Reference

Related

How to get Unique values from json using angular js?

Response code :
In this response eid is repeated, but I want to dispaly only once.
{"response": [
{
"sid": 1,
"eid": "AA",
"ename": "AA11"
},{
"sid": 2,
"eid": "AA",
"ename": "AA11"
}
],
"status": "success"
}
You could use the unique filter from AngularUI
<p ng-repeat="x in data.response | unique: 'ename'">{{x.ename}}</p>
DEMO
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<p ng-repeat="x in data.response | unique: 'ename'">{{x.ename}}</p>
<script>
//App declaration
var app = angular.module('myApp',['ui.filters']);
//Controller Declaration
app.controller('myCtrl',function($scope){
$scope.data = {"response": [
{
"sid": 1,
"eid": "AA",
"ename": "AA11"
},{
"sid": 2,
"eid": "AA",
"ename": "AA11"
}
],
"status": "success"
};
});
</script>
</body>
</html>
There is no magic way. This task should primarily be completed before the response lands the client (on server).
What you can do is make a function which handles the response the way you prefer.
e.g.
//Removes duplicates of eid property
function getUniqueValues(input) {
var output = [];
function existsInOutput(element) {
return output.map(function(val) {
return val.eid
}).includes(element.eid)
};
angular.forEach(input,function(val, key) {
if (!existsInOutput(val)) {
output.push(val);
}
})
return output;
}

Update document in a JSON Collection using AngularJS

I would like to update document in a JSON Collection using AngularJS
My JSON Collection:
$Scope.employee = {
"staff" :
[
{
"id" : 1,
"Name" : "John",
"email" : "john#abc.com"
},
{
"id" : 2,
"Name" : "Watson",
"email" : "watson#abc.com"
},
{
"id" : 3,
"Name" : "jack",
"email" : "jack#abc.com"
},
{
"id" : 4,
"Name" : "Jim",
"email" : "jim#abc.com"
},
{
"id" : 5,
"Name" : "Rose",
"email" : "rose#abc.com"
}
]
};
Now I need to update the document where Id = 2 to
$Scope.updateEmployee = {
"id" : 2,
"Name": "Emma",
"email": "emma#abc.com"
};
Kindly assist me how to replace a particular document and I would like to update the email of id = 5 to hr#abc.com
You can do this,
$scope.update = function(){
$scope.employee.staff.forEach(function (item) {
if (item.id == 2 ) {
item.Name = "Emma";
item.email ="emma#abc.com";
};
});
}
DEMO
$scope.updateItem = function(item) {
for (var i = 0; i < $cope.employee.staff.length; i++) {
if (item.id === $scope.employee.staff[i].id) {
$scope.employee.staff[i] = item;
break;
}
}
}
Now if you want to update $Scope.employee with id 5, just do :
$scope.updateItem({
id: 5,
Name: 'bill',
email: 'test#test.fr'
});
You can do it using underscore.js
Plunker
Basically, you should refrain from traversing your entire list because this can cause some performance related issues. What underscore.js will do is that it will return as soon as it finds an acceptable element, and doesn't traverse the entire list.
Read the official documentation here
find_.find(list, predicate, [context]) Alias: detect
Looks through each value in the list, returning the first one that passes a
truth test (predicate), or undefined if no value passes the test. The
function returns as soon as it finds an acceptable element, and
doesn't traverse the entire list.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.employee = {
"staff": [{
"id": 1,
"Name": "John",
"email": "john#abc.com"
}, {
"id": 2,
"Name": "Watson",
"email": "watson#abc.com"
}, {
"id": 3,
"Name": "jack",
"email": "jack#abc.com"
}, {
"id": 4,
"Name": "Jim",
"email": "jim#abc.com"
}, {
"id": 5,
"Name": "Rose",
"email": "rose#abc.com"
}]
};
$scope.update = function() {
var index = _.findIndex($scope.employee.staff, function(o) {
return o.id == 2;
})
$scope.employee.staff[index].Name = "Emma";
$scope.employee.staff[index].email = "emma#abc.com";
}
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('
<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="emp in employee.staff ">
<div>{{emp.id}} {{emp.Name}}</div>
</div>
<button ng-click="update()">
Update
</button>
</body>
</html>

bind select from api using angularJS

I'm trying to populate a Select getting data from a webapi using ng-options.
Basically, my webapi returns the following JSON:
{
"items":[
{
"name":"X",
"id":1
},
{
"name":"Y",
"id":2
}
]
}
And I Need to generate options in a select displaying the name property, but with the id as value.
The problem is that I can't display my options using ng-options. Here's what I'm trying:
<html ng-app='app'>
<head>
<title>angular</title>
</head>
<body ng-controller='DemoCtrl'>
<select ng-model="selectedTestAccount" ng-options="option.name for option in testAccounts">
<option value="">Select Account</option>
</select>
<script src='https://code.angularjs.org/1.5.0-rc.0/angular.min.js'></script>
<script>
angular.module('app', []).controller('DemoCtrl', function ($scope, $http) {
$scope.selectedTestAccount = null;
$scope.testAccounts = [];
$http({
method: 'GET',
url: '/api/values',
data: {}
}).success(function (result) {
console.log(result);
$scope.testAccounts = JSON.parse(result.items);
});
});
</script>
</body>
</html>
I hope this helps you
angular.module("app", []);
angular.module("app").controller("ctrl", function($scope) {
$scope.testAccounts = [];
var youJson = [
{ "items": [{ "name": "X", "id": "your value for X" }, { "name": "Y", "id": "your value for Y" }] },
{ "items": [{ "name": "A", "id": "your value for A" }, { "name": "B", "id": "your value for B" }] }
];
angular.forEach(youJson, function(items) {
angular.forEach(items.items, function(item) {
$scope.testAccounts.push(item);
});
});
console.log($scope.testAccounts);
});
<!doctype html>
<html ng-app="app" ng-controller="ctrl">
<head>
</head>
<body>
<select ng-model="mySelect" ng-options="item.id as item.name for item in testAccounts"></select>
{{mySelect}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.0/angular.js"></script>
</body>
</html>

tags-input show a a element of an array

hi i have a JSON like this:
pages[
{
"id": "74682309",
"labels": [
{
"term": "test1",
"probability": 0.069
},
{
"term": "test2",
"probability": 0.037
}
]
}];
and using tags-input i want the tags to read only the term and show the term so i can show and update.
i have
<tags-input ng-model="se.labels"></tags-input>
the 'se' comes from ng-repeat="se in searchCtrl.pages
Based on the documentation (http://mbenford.github.io/ngTagsInput/documentation/api) you can change the keyProperty and displayProperty to make it use "term" instead of "text"
I've created a fiddle to demonstrate how you can obtain the data needed, considering that the provided JSON is a valid JSON. Your JSON is invalid.
var myApp = angular.module('myApp',['ngTagsInput']);
myApp.factory('data', function() {
var data = [
{
"id": "74682309",
"labels": [
{
"text": "test1",
"probability": 0.069
},
{
"text": "test2",
"probability": 0.037
}
]
}];
return data;
});
myApp.controller('MyCtrl', ['$scope', 'data', function($scope, data) {
var values = [];
data.map(function(elem) {
return elem.labels.forEach(function(el) {
values.push({
"text" : el.text
});
});
});
$scope.tags = values;
}]);
And the html part:
<div ng-controller="MyCtrl">
<div class="elem">
<tags-input ng-model="tags"></tags-input>
</div>
</div>
Here is the fiddle:
http://jsfiddle.net/HB7LU/16554/
Update:
You haven't included the angular ng-tags-input extension as a tag into your question. Please see my updated fiddle:
http://jsfiddle.net/HB7LU/16557/

Problems facing while working on Isolated Scope concept of Angular

I am trying to extend the example/answer (given by #sylwester) of the question I asked. Now I have to do something like this
What I have done so far?
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
var arr1 = [
{"EmpId":1,"EmpName":"Michale Sharma","gender":"Male","age":25,"salary":10000},
{"EmpId":2,"EmpName":"Sunil Das","gender":"Male","age":24,"salary":5000},
{"EmpId":3,"EmpName":"Robin Pandey","gender":"Male","age":35,"salary":45000},
{"EmpId":4,"EmpName":"Mona Singh","gender":"Female","age":27,"salary":12000}
];
var arr2 = [
{"Deptid":4,"Deptname":"IT"},
{"Deptid":1,"Deptname":"HR"},
{"Deptid":3,"Deptname":"HW"},
{"Deptid":2,"Deptname":"HW4"}
];
var res = merge(arr1, arr2, "EmpId", "Deptid");
$scope.Employee = {
EmployeeName:res.EmpName,
EmployeeSex:res.gender
};
$scope.Department = {
DepartmentName:res.Deptname
};
//console.log(res);
}).
directive('myCustomer', function() {
return {
restrict: 'E',
scope: {
customer: '='
},
templateUrl: 'my-customer-plus-vojta.html'
};
});
function merge(arr1, arr2, prop1, prop2)
{
//alert("in merge");
return arr1.map(function(item){
var p = item[prop1];
var el = arr2.filter(function(item) {
return item[prop2] === p;
});
if (el.length === 0) {
return null;
}
var res = {};
for (var i in item) {
if (i !== prop1) {
res[i] = item[i];
}
}
for (var i1 in el[0]) {
if (i1 !== prop2) {
res[i1] = el[0][i1];
}
}
return res;
}).filter(function(el){return el !== null;});
}
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link href="style.css" rel="stylesheet" />
<script data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js" data-require="angular.js#1.3.x"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<table border="1">
<tr>
<td>EmployeeNames</td>
<td>Gender</td>
<td>Works For</td>
</tr>
<tr>
<my-customer customer="Employee"></my-customer>
<my-customer customer="Department "></my-customer>
</tr>
</table>
</body>
</html>
my-customer-plus-vojta.html (I am stuck here considering other things are correct. I equally know that li is not the correct way to use. However, I do not know what to do and how to do).
<h3>Employee-Department</h3>
<li ng-repeat="emp in customer.Employee">
<p ng-if="emp.EmployeeName">{{emp.EmployeeName}}</p>
<p ng-if="emp.EmployeeSex">{{emp.EmployeeSex}}</p>
</li>
<li ng-repeat="dept in customer.Department">
<p ng-if="dept.DepartmentName">{{dept.DepartmentName}}</p>
</li>
Please see demo below
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
var arr1 = [{
"EmpId": 1,
"EmpName": "Michale Sharma",
"gender": "Male",
"age": 25,
"salary": 10000
}, {
"EmpId": 2,
"EmpName": "Sunil Das",
"gender": "Male",
"age": 24,
"salary": 5000
}, {
"EmpId": 3,
"EmpName": "Robin Pandey",
"gender": "Male",
"age": 35,
"salary": 45000
}, {
"EmpId": 4,
"EmpName": "Mona Singh",
"gender": "Female",
"age": 27,
"salary": 12000
}
];
var arr2 = [{
"Deptid": 4,
"Deptname": "IT"
}, {
"Deptid": 1,
"Deptname": "HR"
}, {
"Deptid": 3,
"Deptname": "HW"
}, {
"Deptid": 2,
"Deptname": "HW4"
}];
$scope.res = merge(arr1, arr2, "EmpId", "Deptid");
});
app.directive('myCustomer', function() {
return {
restrict: 'AE',
scope: {
customer: '=myCustomer'
},
replace: true,
templateUrl: 'customerTmpl.html',
link: function(scope) {
console.log(scope)
}
};
});
function merge(arr1, arr2, prop1, prop2) {
//alert("in merge");
return arr1.map(function(item) {
var p = item[prop1];
var el = arr2.filter(function(item) {
return item[prop2] === p;
});
if (el.length === 0) {
return null;
}
var res = {};
for (var i in item) {
if (i !== prop1) {
res[i] = item[i];
}
}
for (var i1 in el[0]) {
if (i1 !== prop2) {
res[i1] = el[0][i1];
}
}
return res;
}).filter(function(el) {
return el !== null;
});
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="MainCtrl">
<table class="table table-striped">
<tbody>
<tr ng-repeat="customer in res" my-customer="customer"></tr>
</tbody>
</table>
<script type="text/ng-template" id="customerTmpl.html">
<tr>
<td>{{customer.EmpName}}</td>
<td>{{customer.gender}}</td>
<td>{{customer.age}}</td>
<td>{{customer.salary}}</td>
<td>{{customer.Deptname}}</td>
</tr>
</script>
</body>
The problem is you can't just link to res.EmpName... Your res variable is an Array of Objects. You need to loop through that Array, then look inside that Object to grab what you need. Then, you can supply it as a part of your $scope key/value.
For example the 1st key of your res object:
Deptname: "HR"
EmpName: "Michale Sharma"
age: 25
gender: "Male"
salary: 10000
Create empty arrays for your new collections you need to make, then loop through the res object and add them to it.
var empNames = [],
empGenders = [],
empDepts = [];
for (key in res) {
empNames.push(res[key].EmpName);
empGenders.push(res[key].gender);
empDepts.push(res[key].Deptname);
}
// NOW you can apply them into your scope
$scope.Employee = {
EmployeeName : empNames,
EmployeeSex : empGenders
};
$scope.Department = {
DepartmentName : empDepts
};

Resources