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;
Related
I have written a web service returning json array . The following function returns the data in List:
List<ValPair> result = _service.getAllGroupsTypes(P_ClientID);
var jsonSerial = new JavaScriptSerializer();
var jsonResult = jsonSerial.Serialize(result);
return Json(jsonResult, JsonRequestBehavior.AllowGet);
Client Side code :
$scope.getAllGroups = function()
{
var Parameters = { "P_ClientID": 1 };
$http.post("/SMS/getAllGroups", Parameters)
.then(function success(response) {
$scope.received = response.data;
$scope.names = [{ "name": "G1", "value": "1" }] //Just for test purpose
})
}
On the client side BATARANG is displaying scope variable as:
received: [{"Key":"Default Group","Value":"1"}]
names:
[ {
name: G1
value: 1
} ]
Angular is processing the $scope.names in ng-repeat where as not showing any result for $scope.received. As both are array, "names" is hard coded one retrieved from db.
Just change your code to this:
var Parameters = { "P_ClientID": 1 };
$http.post("/SMS/getAllGroups", Parameters)
.then(function success(response) {
$scope.received = JSON.parse(response.data);
$scope.names = [{ "name": "G1", "value": "1" }] //Just for test purpose
})
Output will be:
received: [
{ Key:"Default Group",
Value:"1"}
]
//
names:
[ {
name: G1
value: 1
} ]
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.
I am trying to read data from services using restful service. when I have one json object I am getting the issue. here is my code:
service code:
var ROAList =[];
var promise = $http.post(urlBase + '/' + 'getROAList', params)
.success(function (data) {
ROAList = data.item;
return ROAList;
})
.error(function (data) {
ROAList = 'error';
return ROAList;
});
return promise;
In Controller:
var list =[];
$scope.ROAListItem = function(){
list =service.getROAList();
}
In html:
<div ng-repeat="roa in list()" ng-click ="selectROAitem(roa.soa.name)">
<div> {{roa.id}} </div>
<div> {{roa.soa.name}}</div>
here is my json data:
{"item": [
{
"id":"001",
"type":"001x2z"
"sao": {
"itemNo": "3",
"name": "001"
},
},
{
"id":"002",
"type":"002x2g"
"sao": {
"itemNo": "5",
"name": "006"
}
]}
it working fine for more than one item but I am getting an error for one item. for this json data:
{"item":{
"id":"001",
"type":"001x2z"
"sao": {
"itemNo": "3",
"name": "001"
}
}
for this data ,I am getting 'cannot read property 'name' of undefined.
Removed long winded answer. I didn't see your last section. Your multiple returns are all stored in an array, while your single return is not. So the dot access is incorrect for the single object.
In response to comment: again, you should really format the return data so that it's always in array, but otherwise you could do something like:
$scope.ROAListItem = function(){
list = service.getROAList();
if(!Array.isArray(list)){
list = [list];
}
}
A quick solution would be to modify your service call like so:
$http.post(urlBase + '/' + 'getROAList', params)
.success(function (data) {
ROAList = data.item;
if (!angular.isArray(ROAList)) {
ROAList = [ ROAList ];
}
return ROAList;
})
However, your service really should provide consistent behavior, returning an array even if there is only one item.
I have the following code and after the first query the response data is undefined? Does anyone know the reason behind this?
--- json data ---
{
"weddings": [
{
"id": "1",
"name": "D",
"currency": [
{"USD": "10"},
{"KHR": "20000"}
],
"date": "12/12/2012",
"place": "Bopha Tep",
"paid": false
},
{
"id": 2,
"name": "C",
"currency": [
{"USD": "10"},
{"THB": "200"}
],
"date": "13/12/2012",
"place": "Bopha Charkasamrong",
"paid": false
},
{
"id": 3,
"name": "A",
"currency": [
{"KHR": "10000"},
{"THB": "200"}
],
"date": "14/12/2012",
"place": "Bopha Charkasamrong",
"paid": false
},
{
"id": 4,
"name": "B",
"currency": [
{"KHR": "20000"},
{"THB": "100"},
{"USD": "20"}
],
"date": "15/12/2012",
"place": "Bopha Charkasamrong",
"paid": false
}
]
}
--- Factory ---
.factory('WeddingService',['$resource',function($resource){
var path = 'app/scripts/factories/data/weddings.json';
var data;
var resource = $resource(path,{},{
query: { method: "GET", isArray: false }
});
var weddings = function(){
resource.query().$promise.then(function(response){
data = response.weddings;
});
return data;
}
return {
list: function(){
if(data){
console.log("returning cached data");
return data;
}else{
console.log("getting countries from server");
return weddings();
}
},
get: function(find_id){
return _.findWhere(this.list(),{id:find_id});
},
}
}])
--- Controller ---
$scope.weddings = wedding.list();
console.log($scope.weddings);
---Log---
getting countries from server
undefined
Fetching the data from the server is async so you need to use the promise from the resource to know when the data has been resolved and to get the data. See https://docs.angularjs.org/api/ngResource/service/$resource specifically search for $promise also see this other SO post:
AngularJS resource promise
Forgot about this post but
.factory('WeddingService',['$resource',function($resource){
var path = 'app/scripts/factories/data/weddings.json';
var data;
var resource = $resource(path,{},{
query: { method: "GET", isArray: false }
});
var weddings = function(){
//this will return the promise from the call to .then
return resource.query().$promise.then(function(response){
data = response.weddings;
});
}
return {
list: function(){
if(data){
console.log("returning cached data");
return $q.when(data); // return a promise to keep it consistent
}else{
console.log("getting countries from server");
return weddings();
}
},
get: function(find_id){
return _.findWhere(this.list(),{id:find_id});
},
}
}])
controller
wedding.list().then(function(data){
$scope.weddings = data;
console.log(data);
});
In reality I'd typically just make a reference to WeddingService from the scope or controller definition and access the data through the factory in most cases, but having the setup to return a promise for the data works well to expose the async nature of the request.
It seems you are using data before it is set
var weddings = function(){
resource.query().$promise.then(function(response){
data = response.weddings;
});
// data is not set until the query above is completed
return data;
}
You need to either return the promise and wait for that when using the code, or use the $broadcast('event'); and $on('event', function() { }) event system to trigger your other code when the data is downloaded completely.
You can use the first option like the following:
var weddings = function(){
data = resource.query(function(result) {
console.log('wedding is set to ', result);
},
function(error) {
console.error('something went wrong ', error);
});
return data;
}
Now in your code that uses weddings() you can use $promise to wait for the data and if the query is complete, you can use data like you normally would.
When using bindings from angular html you can also use data directly, since the view will be updated when the data is downloaded.
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.