AngularJS : how to get data from angular resolve? - angularjs

here is the fiddle to my problem http://jsfiddle.net/gxbwk6dk/7/
I have one service to find the element of a json ,
and I am calling that service from the controller twice but the results i am getting from both calls are the same.
in the example elementObj1 and elementObj2 has the same data
Any solution will be welcome.
var app=angular.module("myapp",[]);
app.controller("myctrl",function($scope,myservice)
{
console.log("add of two "+myservice.addTwo(5,7));
$scope.sum=myservice.addTwo(5,7);
$scope.sampleObj={
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
};
myservice.findElement($scope.sampleObj,'GlossEntry').then(function(data){
$scope.elementObj1=data;
console.log("find element object1 ", $scope.elementObj1);
});
myservice.findElement($scope.sampleObj,'GlossList').then(function(data){
$scope.elementObj2=data;
console.log("find element object2 ", $scope.elementObj2);
});
}
);
app.factory("myservice",function($q,$timeout){
var deferred = $q.defer();
return{
addTwo:addTwo,
findElement:findEle,
sample:sample
};
function sample(jsObject)
{
var deferred = $q.defer();
$timeout(function(){deferred.resolve(jsObject)},5000);
return deferred.promise;
}
function addTwo(a,b)
{
return a+b;
}
function findEle(jsObject,searchEle)
{
for(obj in jsObject)
{
console.log("obj "+obj+" mapobj "+jsObject[obj]);
if(obj===searchEle)
{
console.log("element found "+obj);
deferred.resolve(jsObject[obj]);
}
if(typeof jsObject[obj]==="object")
findEle(jsObject[obj],searchEle);
}
return deferred.promise;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myapp" ng-controller="myctrl">
<input type="text" ng-model="name" />
<h2 ng-bind="name"></h2>
display object 1
<table>
<tr ng-repeat="(key, value) in elementObj1">
<td> {{key}} </td> <td> {{ value }} </td>
</tr>
</table>
display object 2
<table>
<tr ng-repeat="(key, value) in elementObj2">
<td> {{key}} </td> <td> {{ value }} </td>
</tr>
</table>
</body>

Here are one working solution: http://jsfiddle.net/gxbwk6dk/9/
You are returning same object, I have modified when you have a hit:
if (obj === searchEle) {
deferred = $q.defer();
deferred.resolve(jsObject[obj]);
}

Related

Show nested data from JSON in table angular

I am trying to show nested data from JSON in a table but not getting succeeded.
My json data:-
$scope.data = [
{
"$id": "1",
"Folder": [
{
"Name": "Windows-Desktop",
"CPU": "2",
"RAM": 2,
"FolderName": "Folder-28"
},
{
"Name": "Desktop",
"CPU": "1",
"RAM": 1,
"FolderName": "Folder-11"
}
]
}
]
I tried this in controller:-
$scope.Folder = [];
angular.forEach($scope.data.Folder, function(choose) {
$scope.Folder.push(choose);
}
In view I did this
<tbody>
<tr role="row" class="odd">
<td class="sorting_1" ng-repeat="g in Folder">{{g.Name}}</td>
<td>
<div ng-repeat="g in Folder">
<input class="form-control" type="text">{{g.CPU}}</input>
</div>
</td>
<td>
<div ng-repeat="g in Folder">
<input class="form-control" type="text">{{g.RAM}}</input>
</div>
</td>
</tr>
</tbody>
I am not getting any output in this. Where am I going wrong?
You are accessing $scope.data.Folder which is not correct because $scope.data is an Array.
First try to loop on $scope.data and then a loop on Folder
$scope.Folder = [];
angular.forEach($scope.data, function(choose) {
if(choose && choose.Folder && choose.Folder.length) {
angular.forEach(choose.Folder, function(choose1) {
$scope.Folder.push(choose1);
}
}
}
In your controller do like this:
$scope.Folder = [];
angular.forEach($scope.data, function(choose) {
if(choose && choose.Folder){
$scope.Folder.push(choose.Folder);
}
})
You need to use $scope.data[0].Folder in your controller as $scope.data is a array type. And I am not sure how you are rendering your table but as the question is only related to getting the value in $scope.Folder this is your solution.
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.data = [
{
"$id": "1",
"Folder": [
{
"Name": "Windows-Desktop",
"CPU": "2",
"RAM": 2,
"FolderName": "Folder-28"
},
{
"Name": "Desktop",
"CPU": "1",
"RAM": 1,
"FolderName": "Folder-11"
}
]
}
];
$scope.Folder = [];
angular.forEach($scope.data[0].Folder, function(choose) {
$scope.Folder.push(choose);
});
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<tbody>
<tr role="row" class="odd">
<td class="sorting_1" ng-repeat="g in Folder">{{g.Name}}</td>
<td>
<div ng-repeat="g in Folder">
<input class="form-control" type="text" />{{g.CPU}}
</div>
</td>
<td>
<div ng-repeat="g in Folder">
<input class="form-control" type="text" />{{g.RAM}}
</div>
</td>
</tr>
</tbody>
</div>
Here is one more example that I think is something you are expecting
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.data = [
{
"$id": "1",
"Folder": [
{
"Name": "Windows-Desktop",
"CPU": "2",
"RAM": 2,
"FolderName": "Folder-28"
},
{
"Name": "Desktop",
"CPU": "1",
"RAM": 1,
"FolderName": "Folder-11"
}
]
}
];
$scope.Folder = [];
angular.forEach($scope.data[0].Folder, function(choose) {
$scope.Folder.push(choose);
});
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<table border='1'>
<tr>
<th>Name</th>
<th>CPU</th>
<th>RAM</th>
</tr>
<tr ng-repeat = "g in Folder">
<td>{{g['Name']}}</td>
<td>{{g['CPU']}}</td>
<td>{{g['RAM']}}</td>
</tr>
</table>
</div>
You can try the following
<div ng-repeat="item in data">
<div ng-repeat="g in item.Folder">
Name:{{g.Name}}-
Cpu:{{g.CPU}}-
Ram:{{g.RAM}}
</div>
</div>
using above method would eliminate the need of preparing data in your controller
Demo
Table Demo
All you need to do is update your iterator function
from
angular.forEach($scope.data.Folder, function(choose)
to
angular.forEach($scope.data[0].Folder, function(choose)
look at your json Folder is first element....

Why does the Ajax not updating the model correctly?

I am new to angularjs and is using code sample in book "pro-angularjs" to do some test run (it has an initial list of items, but then use Ajax to update list):
<!DOCTYPE html>
<html ng-app="todoApp">
<head>
<title>TO DO List</title>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
<script src="angular.js"></script>
<script>
var model = {
user: "Adam",
items: [{ action: "Buy Flowers", done: false },
{ action: "Get Shoes", done: false },
{ action: "Collect Tickets", done: true },
{ action: "Call Joe", done: false }],
};
var todoApp = angular.module("todoApp", []);
todoApp.run(function ($http) {
$http.get("todo.json").then(function successCallback(data) {
model.items = data;
});
});
todoApp.filter("checkedItems", function () {
return function (items, showComplete) {
var resultArr = [];
angular.forEach(items, function (item) {
if (item.done == false || showComplete == true) {
resultArr.push(item);
}
});
return resultArr;
}
});
todoApp.controller("ToDoCtrl", function ($scope) {
$scope.todo = model;
$scope.incompleteCount = function () {
var count = 0;
angular.forEach($scope.todo.items, function (item) {
if (!item.done) { count++ }
});
return count;
}
$scope.warningLevel = function () {
return $scope.incompleteCount() < 3 ? "label-success" : "label-warning";
}
$scope.addNewItem = function (actionText) {
$scope.todo.items.push({ action: actionText, done: false });
}
});
</script>
</head>
<body ng-controller="ToDoCtrl">
<div class="page-header">
<h1>
{{todo.user}}'s To Do List
<span class="label label-default" ng-class="warningLevel()"
ng-hide="incompleteCount() == 0">
{{incompleteCount()}}
</span>
</h1>
</div>
<div class="panel">
<div class="input-group">
<input class="form-control" ng-model="actionText" />
<span class="input-group-btn">
<button class="btn btn-default"
ng-click="addNewItem(actionText)">Add</button>
</span>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Description</th>
<th>Done</th>
</tr>
</thead>
<tbody>
<tr ng-repeat=
"item in todo.items | checkedItems:showComplete | orderBy:'action'">
<td>{{item.action}}</td>
<td><input type="checkbox" ng-model="item.done" /></td>
</tr>
</tbody>
</table>
<div class="checkbox-inline">
<label><input type="checkbox" ng_model="showComplete"> Show Complete</label>
</div>
</div>
</body>
</html>
the only change i made was:
todoApp.run(function ($http) {
$http.get("todo.json").then(function successCallback(data) {
model.items = data;
});
});
it was initially:
$http.get("todo.json").success(function (data) {
model.items = data;
});
which does not run with the latetest version angularjs, and so i made the change.
when debugging, i found that the initial value of model.items is:
and it is correctly showing in UI (see left side of screenshot).
After the ajax, its value is updated to 'data' whose value is:
the value of data looks fine to me (same as initial value of items).
But after i let go the debugger, finally in UI all items are gone.
I do understand why? it seems 'items' is the same as 'data'. Anyone has a clue on how i can debug further to find out the root cause?
Thanks,
btw, the 'todo.json' i used is below:
[{ "action": "Buy Flowers", "done": false },
{ "action": "Get Shoes", "done": false },
{ "action": "Collect Tickets", "done": true },
{ "action": "Call Joe", "done": false }]
You are not updating your model correctly. As you can see from your screenshot, data contains an object data which should be assigned to your model.
todoApp.run(function ($http) {
$http.get("todo.json").then(function successCallback(data) {
model.items = data.data;
});
});

AngularJS JSON load from file with ng-click

Currently I want to show HTML table by parsing JSON data from file using Angular JS, And It's not working can someone please help me?
And Also As a Enhancement How Can I get the 2 Divs for 2 different JSON file
HTML Code
<html>
<div ng-controller="get_controller">
<input type="text" ng-model="accountnumber" name="accountnumber" class="form-control search-query" placeholder="Enter Account Number">
<span class="input-group-btn">
<button type="submit" ng-click="geValues()" class="btn btn-primary">Submit</button>
</span>
</div>
<div ng-controller="get_controller">
<table>
<tbody>
<tr>
<th ng-repeat="list in personDetails">{{list.Name}}
</th>
</tr>
<tr>
<td class="features" ng-repeat="list in personDetails">{{list.Location}}
</td>
</tr>
</tbody>
</table>
</div>
</html>
Angular JS Code
var app = angular.module('myApp', ["ngTable"]);
app.controller('get_controller', function ($scope, $http) {
$scope.geValues = function() {
$http({method: 'POST', url: 'posts.json'}).success(function(data) {
$scope.post = data;
$scope.personDetails = Employee;
})
},
});
posts.json (Json File)
{
"Employee": [
{
"Name": "Rocky",
"Location": "Office"
},
{
"Name": "John",
"Location": "Home"
}
]
}
Should be a GET request, also the you need to access the data from the response object which contains the Employee array. Code should be,
$http.get('test.json').then(function (response){
$scope.post = response.data;
$scope.personDetails = response.data.Employee;
});
if you want it to happen on ng-click, put the call inside a function,
$scope.geValues = function() {
$http.get('test.json').then(function(response) {
$scope.post = response.data;
$scope.personDetails = response.data.Employee;
});
}
DEMO

how to search using two criterions( select and input)

i'm new in angular js , and i'm trying to search in a my table , using a selectbox.
I want that my search will be based on two xriterion: ( what i will write on the input item , and on what i will select )
for exemple if i will select ( search by name ) , i should search just based on name:
here is my code :
<div ng-controller="mycontrolleur">
<input type='text' ng-model="searchT">
<select ng-model="choix">
<option value='nom'>search by name</option>
<option value='cin'>search by CIN</option>
</select>
<table border="1">
<tr><td>Nom</td><td>CIN</td></tr>
<tr ng-repeat="x in students|filter:searchT|orderBy:choix">
<td>{{x.nom}} </td><td>{{x.cin}}</td></tr>
</table>
</div>
<script src='angular.min.js'></script>
<script>
var app=angular.module('searchApp',[]);
app.controller('mycontrolleur',function($scope)
{
$scope.students=[{nom:'marwen',cin:11155},
{nom:'mounir',cin:15885},
{nom:'maryem',cin:25155},
{nom:'ahmed',cin:77555},
{nom:'amel',cin:88155}
];
});
</script>
thank you for your help guys :)
You can use a filter like this one :
app.filter('filterByCustomProp', function($filter) {
return function(source, prop, searchValue) {
if (!searchValue) return source;
if (!prop) return $filter('filter')(source, searchValue); //search on name & CIN
return source.filter(function(item) {
return (item[prop].toString().indexOf(searchValue) > -1);
});
};
});
Then you can call :
<tr ng-repeat="x in students|filterByCustomProp:choix:searchT|orderBy:choix">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="searchApp" ng-controller="mycontrolleur">
<input type='text' ng-model="searchT">
<select ng-model="choix">
<option value='nom'>search by name</option>
<option value='cin'>search by CIN</option>
</select>
<table border="1">
<tr>
<td>Nom</td>
<td>CIN</td>
</tr>
<tr ng-repeat="x in students|filterByCustomProp:choix:searchT|orderBy:choix">
<td>{{x.nom}}</td>
<td>{{x.cin}}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('searchApp', []);
app.filter('filterByCustomProp', function($filter) {
return function(source, prop, searchValue) {
if (!searchValue) return source;
if (!prop) return $filter('filter')(source, searchValue); //search on name & CIN
return source.filter(function(item) {
return (item[prop].toString().indexOf(searchValue) > -1);
});
};
});
app.controller('mycontrolleur', function($scope) {
$scope.students = [{
nom: 'marwen',
cin: 11155
}, {
nom: 'mounir',
cin: 15885
}, {
nom: 'maryem',
cin: 25155
}, {
nom: 'ahmed',
cin: 77555
}, {
nom: 'amel',
cin: 88155
}];
});
</script>
Hello you can use filter by object. For example:
ng-repeat="client in clients | filter: {name: 'Brett', designation: '1'}"

Dynamic Select Boxes in Angular ng-repeat

I'm an old "backender" and pretty new to Angular and modern frontend programming, but I have to learn...
I have the following problem: There is a list with several different person properties, which are created via ng-repeat from Controller response. The values are editable, but the display control depends on the type of the property. The Gender, for example, needs to be edited via a Select-Box. The options for the select box are obtained from a Rest-Server.
So now the main question: How can I build different Select Boxes for each property?
I tried the following code, which is not working:
<section class="contactProperty" ng-repeat="property in contactDetail.properties">
<table>
<tr>
<td>{{property.message}}</td>
<td rowspan=2>{{property.value}}
<script>
var lst = ContactDetailController.getClassification(property.type);
</script>
<input ng-show="{{property.displaystyle_id}}==1" type="text" ng-model="property.value"/>
<select ng-show="{{property.displaystyle_id}}==3" ng-model="property.value">
<option ng-repeat="opt in lst" value="{{opt.id}}">{{opt.message}}</option>
</select>
</td>
</tr>
<tr>
<td>
<select type="text" ng-model="property.status_id">
<option ng-repeat = "status in contactDetail.propertyStatus" value="{{status.id}}">{{status.message}}</option>
</select>
</td>
</tr>
</table>
</section>
The Controller is defined on the top level element with following code
.controller('ContactDetailController',
['$scope', '$rootScope', 'ContactDetailService',
function ($scope, $rootScope, ContactDetailService) {
$scope.getContactDetail = function () {
ContactDetailService.getContactDetail(function(response) {
if(response.success) {
$scope.contactDetail=response;
} else {
$scope.error = response.message;
}
});
};
$scope.getClassifications= function(type) {
ContactDetailService.getClassifications(type, function(response) {
if (response.success) {
return response;
}
});
};
$scope.getContactDetail();
}]);
And the corresponding service:
.factory('ContactDetailService',
['$http', '$rootScope', '$location',
function ($http, $rootScope, $location) {
var service = {};
service.getContactDetail = function(callbackFunc) {
delete $http.defaults.headers.common['X-Requested-With'];
var apiRoot="";
apiRoot = $rootScope.environments[window.location.host];
$rootScope.apiRoot=apiRoot;
var id=$location.search().id;
$http.get(apiRoot+'/contactdetail?id='+id, {})
.success(function(response){
$rootScope.contactDetail=response;
callbackFunc(response);
}).error(function(response){
alert("error"+response.message);
});
};
service.getClassifications = function(type, callbackFunc) {
var apiRoot="";
apiRoot = $rootScope.environments[window.location.host];
$http.get(apiRoot+'/classifications?type='+type, {})
.success(function(response) {
callbackFunc(response);
})
.error(function(response) {
alert("error"+response.message);
});
};
return service;
}]);
Can anyone help me?
you can show/hide fields using ng-show/ng-hide or ng-if or ng-switch depending on your type of variable selected. if this is what you want.
I will try to explain more precisley:
This is a part of my incomming Json from the Backend:
"properties": [
{
"id": 8,
"type_id": 25,
"status_id": 13,
"contact_id": 4,
"value": "27",
"create_date": null,
"update_date": null,
"guikey": "gui.gender",
"message": "Geschlecht",
"displaystyle_id": 3,
"queryparam": "9",
"options": [
{
"id": 26,
"type": 9,
"guikey": "gui.male",
"language": "de",
"message": "Männlich",
"displaystyle_id": 0
},
{
"id": 27,
"type": 9,
"guikey": "gui.female",
"language": "de",
"message": "Weiblich",
"displaystyle_id": 0
}
]
}
],
It is rendered by following code:
<section class="contactProperty" ng-repeat="property in contactDetail.properties">
<table>
<tr>
<td>{{property.message}}</td>
<td rowspan=2 ng-switch on="property.displaystyle_id">{{property.value}}
<input ng-switch-when="1" type="text" ng-model="property.value"/>
<input ng-switch-when="2" type="date" ng-model="property.value"/>
<select ng-switch-when="3" ng-model="property.value">
<option ng-repeat="opt in property.options" value="{{opt.id}}">{{opt.message}}</option>
</select>
</td>
</tr>
<tr>
<td>{{property.status_id}}
<select type="text" ng-model="property.status_id">
<option ng-repeat = "status in contactDetail.propertyStatus" value="{{status.id}}">{{status.message}}</option>
</select>
</td>
</tr>
</table>
</section>
The resulting HTML contains a Select box as expacted:
<section class="contactProperty ng-scope" ng-repeat="property in contactDetail.properties">
<table>
<tbody>
<tr>
<td class="ng-binding">Geschlecht</td>
<td class="ng-binding" on="property.displaystyle_id" ng-switch="" rowspan="2">
27
<select class="ng-scope ng-pristine ng-valid" ng-model="property.value" ng-switch-when="3">
<option class="ng-binding ng-scope" value="26" ng-repeat="opt in property.options">Männlich</option>
<option class="ng-binding ng-scope" value="27" ng-repeat="opt in property.options">Weiblich</option>
</select>
</td>
</tr>
<tr>
</tbody>
</table>
</section>
But the Browser displays the Value "Männlich" in this example, but I expected to see "Weiblich" because the property.value 27 is passed from the json. I just show the value for debug as {{property.value}} and it shows 27, which is correct. I don't understand why the dropdown still showing the first entry (26/Männlich) in this case...

Resources