Use json object as variable in controller via ngResource - angularjs

I fetch json data via ngResource angular, it is easy to use in view by using {{ }} but i don't know how to put these json objects to variable.
var workersServices = angular.module('workersServices', ['ngResource']);
workersServices.factory('Worker', ['$resource',
function($resource){
return $resource('workers/:workerId.json', {}, {
query: {method:'GET', params:{workerId:'workers'}, isArray:true}
});
}]);
var workersControllers = angular.module('workersControllers', []);
workersControllers.controller('costsCtrl', ['$scope','Worker', function($scope, Worker) {
$scope.workers = Worker.query();
HERE I WANT NAME PROPERTY AT THAT SCOPE :
**$scope.janeDoeName = workers[0].name; ??? IT DOESNT WORK**
}]);
JSON DATA workers.json
[
{
"id": "jane-doe",
"name": "Jane Doe",
"department": "sales",
"period": {
"start": "2015-12-14",
"finish": "2018-12-14",
"periodOfNotice": false
},
"paymentHour": 20,
"hours": 168
}]
I just want to put chosen property from that json to $scope and use it later in some functions.

You can try a callback function in the query:
var workersControllers = angular.module('workersControllers', []);
workersControllers.controller('costsCtrl', ['$scope','Worker', function($scope, Worker) {
$scope.workers = Worker.query(function(){
$scope.janeDoeName = $scope.workers[0].name;
});
}]);

Related

AngularRest API wont return JSON property

I have 3 components, the web api, the controller, and the html. I can hit the web api just fine and i get back the results in JSON format, but when it then tries to render the JSON into the html, it looks like this.
{
"Projects": [{
"ProjectId": 1,
"Name": "Project1",
"Key": "Software",
"ProjectTypeKey": "1"
}, {
"ProjectId": 2,
"Name": "Project2",
"Key": "Hardware",
"ProjectTypeKey": "2"
}, {
"ProjectId": 3,
"Name": "Project3",
"Key": "Hardware",
"ProjectTypeKey": "3"
}]
}
WebApi
public IHttpActionResult Get()
{
listProjects.Add(new Project { ProjectId = 1, Name = "Project1", Key = "Software", ProjectTypeKey = "1" });
listProjects.Add(new Project { ProjectId = 2, Name = "Project2", Key = "Hardware", ProjectTypeKey = "2" });
listEmployeeProject.Add(new EmployeeProject {Projects = listProjects });
return Json(listEmployeeProject);
}
Controller
var myApp = angular.module('myApp', []);
myApp.service('dataService', function ($http) {
this.getData = function () {
// $http() returns a $promise that we can add handlers with .then()
return $http({
method: 'GET',
url: '/api/employee'
});
}
});
myApp.controller('ProjectController', function ($scope, dataService) {
$scope.Projects = [];
dataService.getData().then(function (result) {
$scope.Projects = result.data;
});
});
HTML
<div ng-app="myApp" ng-controller="ProjectController">
{{1 + 1}}
<div ng-repeat="project in Projects">
{{project}}
</div>
Even when i switch {{project}} to {{project.Name}}, nothing renders on the page.
console.log(results.data) looks like below
Its very clear from your console that you are returning an array of length 1 which has another array of length 3 in it
This is because of this line in your code
listEmployeeProject.Add(new EmployeeProject {Projects = listProjects });
Here you are retuning a EmployeeProject array and each element of that array has multiple projects. So do either of these things
a. Return listProjects like return Json(listProjects) (You should be returning Ok(model) ideally)
b. Or in angular promise do,
$scope.Projects = result.data[0].Projects;

How to Create table through json object using Angularjs

Console log image
Hi in my code below I am trying to convert xml Data to Json Object. Using converted Json Object I am trying to create a table using angularjs. So here the problem is I am able to bind complete converted json object {{employeeList}} but failed to load individual attribute of json object i.e., {{employee.EmpId}}. Finally from my observation I found when the converted json object is directly assigned to
$scope.Employees = {
"Employee": [{
"EmpId": "4",
"Name": "Chris",
"Sex": "Male",
"Phone": [{
"_Type": "Home",
"__text": "564-555-0122"
},
{
"_Type": "Work",
"__text": "442-555-0154"
}],
"Address": {
"Street": "124 Kutbay",
"City": "Montara",
"State": "CA",
"Zip": "94037",
"Country": "USA"
}
}]
};
the output is what I expected, but when I assign the direct result
i.e, $scope.Employees=response; it is not working. What might be the issue?
<script>
var app = angular.module('httpApp', []);
app.controller('httpController', function ($scope, $http) {
$http.get("File1.xml", {
transformResponse: function (cnv) {
var x2js = new X2JS();
var aftCnv = x2js.xml_str2json(cnv);
return aftCnv;
}
})
.success(function (response) {
console.log(response);
$scope.Employees = response;
console.log($scope.Employees);
});
});
<script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="httpApp">
<div ng-controller="httpController">
<div ng-repeat="employeeList in Employees">
{{employeeList}}
<table>
<tr ng-repeat="employee in Employees.Employee">
<td>{{employee.EmpId}}</td>
<td>{{employee.Name}}</td>
<td>{{employee.Phone._Type}}</td>
<td>{{employee.Phone.__text}}</td>
<td>{{employee.Address.Street}}</td>
<td>{{employee.Address.State}}</td>
<td>{{employee.Phone.Zip}}</td>
<td>{{employee.Phone._text}}</td>
<td>{{employee.Address.Country}}</td>
</tr>
</table>
</div>
</div>
</div>
Ok. The issue is, response.data after the conversion of the xml file has the following structure,
{
"Employees": { // note that the data you need is present in "Employees" field
"Employee": [
... // contains objects with employee details
]
}
}
So, you need to populate $scope.Employees as follows,
// your required data is present in "Employees" field of response.data
$scope.Employees = response.data.Employees;
So, your <script> tag code will be,
<script>
var app = angular.module('httpApp', []);
app.controller('httpController', function ($scope, $http) {
$http.get("File1.xml", {
transformResponse: function (cnv) {
var x2js = new X2JS();
var aftCnv = x2js.xml_str2json(cnv);
return aftCnv;
}
})
.success(function (response) {
// your required data is present in "Employees" field of response.data
$scope.Employees = response.data.Employees;
console.log($scope.Employees);
});
});
</script>
Here is the updated and working plunker.
Also, note that employee.Phone is an array and you need to use ng-repeat again to display the details as I've mentioned in one of the comments.

AngularJS Best Practices for modifying view

I currently have an Angular application with one module. This module defines a controller and a service. I'm currently using the service to update my view. Should services update view logic? Or should this be done in a separate Angular component?
index.html
<div ng-controller="AppController as AppCtrl">
<div id="grid1" ui-grid="{ data: myData }" class="grid"></div>
<button ng-click="AppCtrl.getPeople()" ng-model="AppCtrl.getPeopleButtonText" ng-bind="AppCtrl.getPeopleButtonText"></button>
<button ng-click="AppCtrl.clearPeople()">Clear</button>
{{AppCtrl.errorMessage}}
</div>
app.js
angular.module('app', ['ui.grid'])
.controller('AppController', ['$scope', "PersonService", function ($scope, PersonService) {
var controllerScope = this;
controllerScope.getPeopleButtonText = "Get People";
this.getPeople = function(){
PersonService.getPeople($scope, controllerScope);
};
this.clearPeople = function(){
PersonService.clearPeople($scope, controllerScope);
};
}])
.service("PersonService", ["$http", function($http) {
var refreshCount = 0;
this.getPeople = function(rootScope, controllerScope){
var sampleData = [
{
"firstName": "Cox",
"lastName": "Carney",
"company": "Enormo",
"employed": refreshCount%2 == 1
},
{
"firstName": "Lorraine",
"lastName": "Wise",
"company": "Comveyer",
"employed": refreshCount%2 == 0
},
{
"firstName": "Nancy",
"lastName": "Waters",
"company": "Fuelton",
"employed": refreshCount%2 == 1
}
];
$http.post("https://httpbin.org/post", sampleData)
.success(function(data){
rootScope.myData = JSON.parse(data.data);
refreshCount++;
controllerScope.getPeopleButtonText = "Refresh " + refreshCount;
controllerScope.errorMessage = "";
})
.error(function() {
controllerScope.errorMessage = "An error has occurred."
});
};
this.clearPeople = function(rootScope, controllerScope) {
rootScope.myData = [];
controllerScope.getPeopleButtonText = "Get People";
}
}]);
Is there a better way to structure this code?
Another approach I have read about was to create a ViewService and expose the ViewService into the root scope.
EDIT Nov 19
I'm using an Angular Promise to handle the success/error cases of a service call in a controller, rather than inside the service. This allows me to move view updates into the controller. Is this the right place to keep the view updates?
this.getPeople = function() {
PersonService.getPeople()
.then(function(data) {
$scope.myData = JSON.parse(data);
controllerScope.getPeopleButtonText = "Refresh";
controllerScope.errorMessage = "";
}, function(error) {
controllerScope.errorMessage = "An error has occurred."
});
};
Here's an example plnkr
http://plnkr.co/edit/tzuSX3aAcUqpH5bM7cIa?p=preview
Never use $rootScope to store data
Use the MVC pattern if you like, so:
One view, has one controller, has as many services as you need.
Your view shows data which are in the $scope
Your Controller is getting the data from your PersonService
The PersonService (or just the API service) gets the data from a backend.
Best practices would be like this (simplyfied):
Api.js
angular
.module( 'api', [])
.service('Api', Api);
Api.$inject = ['$http'];
function Api($http) {
var baseUrl = '/api/url/';
function getPersons() {
return $http({
method: 'GET',
url: baseUrl + 'YOUR/PERSON/URL'
});
}
return {
getPersons: getPersons
}
}
PersonController.js
angular
.module('personApp')
.controller('PersonController', PersonController);
PersonController.$inject = ['$scope', '$state', 'Api'];
function PersonController($scope, $state, Api) {
$scope.getPersons = function() {
Api.getPersons().then(function(response) {
$scope.persons = response.data;
}, function(error) {
// error message
});
};
}
Persons.html
<div ng-controller="PersonController">
<div id="grid1" ui-grid="{ data: persons }" class="grid"></div>
<button ng-click="getPersons()"></button>
</div>
Summary
Your view displays the data which is inside the $scope
The view has a controller, which is there for just getting the data and storing it in the $scope, providing the functions for the buttons
Your services are delivering the data to the controller

How to display JSON list data in angularjs

I am new to Angularjs and having trouble displaying data . i.e. Json array
This is the result of my rest service call:
{
"users": [{
"id": 1,
"firstname": "Naveen",
"lastname": "Dutt",
"email": "navee23ndutt12.vyas#gmail.com",
"telephone": "7829418456445355"
}]
}
And this is my controller:
app.controller('MyCtrl2', ['$scope', 'NFactory', function ($scope, NFactory) {
alert("here??");
$scope.bla = NFactory.query;
alert("here??" + $scope.bla);
NFactory.get({}, function (nFactory) {
$scope.allposts = nFactory.firstname;
})
}]);
This is my html:
<div>
<ul >
<li ng-repeat="user in bla"> {{ user.firstname }} </li>
</ul>
</div>
but it doesnt show anything on UI. what can be the problem? please suggest.
It happens because you call async task. I would wrap result with promise.
Here is basic simulation of async call:
Demo Fiddle
var app = angular.module('myModule', ['ngResource']);
app.controller('fessCntrl', function ($scope, Data) {
Data.query()
.then(function (result) {
console.log(result);
$scope.bla = result.users;
}, function (result) {
alert("Error: No data returned");
});
});
app.$inject = ['$scope', 'Data'];
app.factory('Data', ['$resource', '$q', function ($resource, $q) {
var data = {
"users": [{
"id": 1,
"firstname": "Naveen",
"lastname": "Dutt",
"email": "navee23ndutt12.vyas#gmail.com",
"telephone": "7829418456445355"
}]
};
//Actually we can use $resource
//var data = $resource('localhost/shfofx/PHP/Rest/alertLossDetails.php',
// {},
// { query: {method:'GET', params:{}}}
// );
var factory = {
query: function (selectedSubject) {
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
}]);
If $scope.bla in your case is
{"users":[{"id":1,"firstname":"Naveen","lastname":"Dutt","email":"navee23ndutt12.vyas#gmail.com","telephone":"7829418456445355"}]
then your template should look like this:
<ul >
<li ng-repeat="user in bla.users"> {{ user.firstname }} </li>
</ul>
Another way would be to change the code inside your Controller like this:
$scope.bla = NFactory.query.users;
and leave template as you have it.
If NFactory.query is string you need to parse it as JSON first.
$scope.bla=JSON.parse(NFactory.query);
and then
<ul >
<li ng-repeat="user in bla.users"> {{ user.firstname }} </li>
</ul>
Hope this will help...
Shouldn't it be a method call: NFactory.query() ?
Please show the NFactory source.
UPDATE: Try responding just array from server:
[{
"id": 1,
"firstname": "Naveen",
"lastname": "Dutt",
"email": "navee23ndutt12.vyas#gmail.com",
"telephone": "7829418456445355"
}]
and use NFactory.query()

grabbing just required results from json --- restangular

I am trying to grab just few ids from json and not the complete payload of json. Is that possible? here is my code
Car.controller('IndexCtrl', function ($scope, CarRestangular) {
$scope.cars = CarRestangular.all('car').getList();
});
here is my json
[
{
"id": 1,
"name": "Mike",
},
{
"id": 2,
"name": "Floyd",
},
{
"id": 3,
"name": "Roy",
},
{
"id": 4,
"name": "Roy",
},
]
I want to get records where ids are 2 and 4. How could I do that. Also if possible, what would I need to do to get top two records in an other case that I would need.
Thanks
The newer versions of angular don't automatically unproxy promises in scope. Therefore you can't immediatelt do:
$scope.cars = CarRestangular.all('car').getList();
But you have to do:
CarRestangular.all('car').getList().then(function(result){
$scope.cars = result;
));
The filtering would be the best if you have lodash included.
https://gist.github.com/lc-nyovchev/7414166e4dbf2dfbc908
You define a service with a method that does the filtering for you:
.factory('SomeService',['$q', 'Restangular', function($q,Restangular){
return {
someMethod: function(){
var deferred = $q.defer();
Restangular.all('car').getList().then(function(results){
var filtered = _.filter(results, function(result){
return result.id === 2 || result.id === 4;
});
return deferred.promise;
}
};
}])
Then you use the service in your controller:
.controller('YourController', ['SomeService', function(SomeService){
SomeService.someMethod().then(function(filteredResult){
$scope.cars = filteredResult;
});
}]);
Alternatively you can just do:
CarRestangular.all('car').getList().then(function(results){
$scope.cars = _.filter(results, function(result){
return result.id === 2 || result.id === 4;
});
});
Edit: all those answers assume you want to do the filtering client side. IF your backend supports it, you can do something like:
CarRestangular.all('car').getList(id:[2,4]).then(function(result){
$scope.cars = result;
));
And if your backend is written in such a way that is supports filtering on the id attribute, it would return you the correct results and you wouldn't have to filter them.

Resources