How to process an array with AngularJS? - javascript

I have an API returning the following simple JSON array:
[
"efd98ad-first_key",
"100eb0a-second_key"
]
I am trying to render this as a table with Angular:
<div name="listkeys" class="container">
<div class="starter-template">
<div ng-bind-html="message"></div>
<table class="table table-striped table-bordered table-condensed sortable" ng-init="getKeys()">
<tr>
<th>bucket</th>
</tr>
<tr ng-repeat="bucket in buckets">
<td>{{bucket}}</td>
</tr>
</table>
</div>
</div>
JS:
var app = angular.module('flipDaSwitch', ['ngSanitize']);
app.controller('ListKeys', function($scope, $http) {
$scope.getKeys = function() {
$http.get('/api/keys').
success(function (data) {
$scope.response = data;
}).
error(function (data){
$scope.response = {}
});
};
});
It does not do anything but throwing an "Uncaught object" error and that is it.
How could I debug why it is failing?

You are storing the values in $scope.response, but you are using $scope.bucket at the ng-repeat:
$scope.getKeys = function() {
$http.get('/api/keys').
success(function (data) {
$scope.buckets= data;
}).
error(function (data){
$scope.buckets= {}
});
};

It looks like you do not have a scope item called buckets. I'd expect to see:
$scope.buckets = data
Inside the success callback.

Related

Writing the event handlers for next button onclick for datatable in an angularjs controller

I am trying to write an event handler for page change in a datatable. following is the existing code.. the libraries are included in a baselayout for following code..
DefaultView.cshtml
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6 pageheading">
<h1>
<small>AMS Default</small>
</h1>
</div>
</div>
<hr />
<br />
<div class="row">
<div class="col-lg-12">
<table dt-options="dtOptions" datatable dt-columns="dtColumns"
class="table table-striped table-bordered dt-responsive">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
</table>
</div>
</div>
#section CommonScripts{
<script src="~/Angular/Areas/Common/Controllers/DefaultController.js"></script>
<script src="~/Angular/Areas/Common/Services/DefaultService.js"></script>
}
Defaultcontroller.js
AMSApp.controller('DefaultController', ['$rootScope', 'DefaultService', 'DTOptionsBuilder', 'DTColumnBuilder',
function ($rootScope, DefaultService, DTOptionsBuilder, DTColumnBuilder) {
var self = this;
this.Users = {};
this.GetAllUsers = function () {
$rootScope.CloseAlerts();
DefaultService.GetAllUsers().success(function (result) {
self.Users = result;
self.loadd();
}).catch(function (error) {
$rootScope.ErrorMsg = "OOPS some thing went wrong. Please try again.";
});
}
this.GetAllUsers();
this.loadd = function () {
$rootScope.dtColumns = [
DTColumnBuilder.newColumn('DisplayName').withTitle('UserName'),
DTColumnBuilder.newColumn('IsSNA').withTitle('IsSNA'),
DTColumnBuilder.newColumn('IsAdmin').withTitle('IsAdmin'),
DTColumnBuilder.newColumn('IsDownloadPermitted').withTitle('DownloadPermitted')
];
$rootScope.dtOptions = DTOptionsBuilder.newOptions()
.withOption('data', self.Users)
.withDisplayLength(10);
}
}]);
/*
Button Click handler:
$("#customerSearchButton").on("click", function (event) {
$.ajax({
url: "",
type: "post",
data: { searchText: searchText }
}).done(function (result) {
Table.clear().draw();
Table.rows.add(result).draw();
}).fail(function (jqXHR, textStatus, errorThrown) {
// needs to implement if it fails
});
}
*/
DefaultService.js
AMSApp.service('DefaultService', function ($http) {
this.GetAllUsers = function () {
return $http.get('/Common/User/GetAllUsers');
}
});
I tried several versions like in the above-commented code.. but I need something like following in the controller.
/*need something like this*/
DTOptionsBuilder.on('page.dt', function () {
var info = table.page.info();
console.log("hey i got eexecuted");
$('#pageInfo').html('Showing page: ' + info.page + ' of ' + info.pages);
});
firstly is it possible? - if not what are other alternatives?
Note: I prefer not to give an id to the table.

ASP.NET MVC 6 Angular JS Table Update

I'm currently learning new MVC 6 and stucked completely with simple action - table data update on item selection change.The desired behaviour is to load questions that belong selected question block
I have angularJS factory:
(function () {
'use strict';
angular
.module('questionBlockApp')
.factory('questionBlockService', questionBlockService);
var questionBlockService = angular.module('questionBlockService', ['ngResource']);
questionBlockService.factory('Blocks', ['$resource',
function ($resource) {
return $resource('/api/blocks/', {}, {
query: { method: 'GET', params: {}, isArray: true }
});
}]);
questionBlockService.factory('Questions', ['$resource',
function ($resource) {
return $resource('/api/blocks/:blockId', {blockId : '#blockId'}, {
query: { method: 'GET', params: {}, isArray: true }
});
}]);
})();
Controller, which has refresh func (loadQuestions) built inside selection change function:
(function () {
'use strict';
angular
.module('questionBlockApp')
.controller('questionBlockController', questionBlockController);
//.controller('questionController', questionController);
questionBlockController.$inject = ['$scope', 'Blocks', 'Questions'];
//questionController.$inject = ['$scope', 'Questions'];
function questionBlockController($scope, Blocks, Questions) {
$scope.selectedBlock = 2;
if ($scope.Blocks == undefined | $scope.Blocks == null) {
$scope.Blocks = Blocks.query();
}
$scope.setSelected = function (blockId) {
$scope.selectedBlock = blockId;
$scope.loadQuestions();
}
$scope.loadQuestions = function () {
$scope.data = Questions.query({ blockId: $scope.selectedBlock });
$scope.data.$promise.then(function (data) {
$scope.Questions = data;
});
};
$scope.loadQuestions();
}
})();
And views:
View from which setSelected is called:
<table class="table table-striped table-condensed" ng-cloak ng-controller="questionBlockController">
<thead>
...
</thead>
<tbody>
<tr ng-repeat="block in Blocks" ng-click="setSelected(block.Id)" ng-class="{'selected': block.Id == selectedBlock}">
<td>{{block.Id}}</td>
<td>{{block.Name}}</td>
<td>{{block.Created}}</td>
</tr>
</tbody>
</table>
<table id="test" ng-controller="questionBlockController">
<thead>
<tr>
...
</tr>
</thead>
<tbody>
<tr ng-repeat="question in Questions">
<td>{{question.Id}}</td>
<td>{{question.Text}}</td>
<td>{{question.TimeLimit}}</td>
<td>{{question.Updated}}</td>
</tr>
</tbody>
</table>
When I click on different items in QuestionBlock table, $scope.Questions is updated properly, but the table does not reflect changes, as if no binding exists.
Okay, I am just a bit damaged.
There are two questionBlockController controllers defined, leading to intialization of different scopes => two $scope.Questions objects existence => refresh occured in Blocks scope, which was undesired behaviour.

AngularJS - Binding/Replacing AJAX content

I am using AngularJS to load AJAX content and using ng-repeat to create a list of items. On the content I also have {{noun}} as a placeholder. My assumption was that when the ajax content is loaded, AngularJS would automatically replace {{noun}} with the data from $scope.noun model. But it isn't the case. Any quick and dirty way to make it happen?
Here's my code:
AllControllers.controller('AppController', ['$scope', '$http', function ($scope, $http) {
$scope.noun = "My Noun";
$scope.headlines = [{
headline: "Top 10 Tricks to {{noun}}",
usage: 10,
votes: 100
}];
$scope.load_headlines = function() {
$http.get('/data/headlines.json').
success(function(data, status, headers, config){
$scope.headlines = data;
}).
error(function(data, status, headers, config){
console.log(status);
});
};
}]);
<div ng-controller="AppController" ng-init="load_headlines()">
<table>
<tbody ng-repeat="headline in headlines">
<tr>
<td>{{headline.headline}}</td>
<td class="center">{{headline.usage}}</td>
<td class="center">{{headline.votes}}</td>
</tr>
</tbody>
</table>
</div>
Your $scope variable is differently to the ngRepeat variable.
I think you have to change the $scope variable in your controller:
$scope.headlines_displayed = [{
headline: "Top 10 Tricks to "+$scope.noun,
usage: 10,
votes: 100
}];
you can binding the {{moon}} in the td repeated.
change the code like this:
AllControllers.controller('AppController', ['$scope', '$http', function ($scope, $http) {
$scope.noun = "My Noun";
$scope.headlines = [{
headline: "Top 10 Tricks to ",
usage: 10,
votes: 100
}];
}]);
<tbody ng-repeat="headline in headlines_displayed">
<tr>
<td>{{headline.headline}} {{noun}}</td>
<td class="center">{{headline.usage}}</td>
<td class="center">{{headline.votes}}</td>
</tr>
</tbody>
Figured it out. Ended up doing this:
<td>{{headline.headline.replace("{{noun\}\}", noun)}}</td>
You should be using $interpolate service to compile the string before assigning it to the scope. Passing a string with {{}} will not work. In your http success callback do something like this. This will replace your {{noun}} with scope value.
$scope.load_headlines = function() {
$http.get('/data/headlines.json').
success(function(data, status, headers, config){
$scope.headlines = data;
$interpolate($scope.headlines.headline)($scope);
}).
error(function(data, status, headers, config){
console.log(status);
});
};
}]);
Take a look at the the this fiddle

How to properly iterate over an array elements with Angular JS?

I want to render a table adding row per each objects in an array.
I got a Controller like:
app.controller('SignUpController',function ($scope, $http) {
var that = this
that.users = []
that.queryUsers = function() {
console.log("I'm being triggered")
$http.get("/existingUsers").
success(function (data,status,headers,config) {
console.log(data)
that.users = data
console.log(that.users)
}).
error(function (data,status, headers, config) {
console.log(status)
})
}
})
And the table markup:
<table class="table table-bordered">
<th ng-repeat="th in ['mail','Administrador','Miembro desde']">{{th}}</th>
<tr ng-repeat="p in signup.users">
<td>{{p._id}}</td>
<td>{{p.mail}}</td>
<td>{{p.admin}}</td>
</tr>
</table>
Ttable is within a div with ng-controller="SignUpController as signup". When I click a button I trigger queryUsers actually seein results in browser console:
[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]
Both mail and _id are existing attributes per each object.
So the AJAX is being done and the array I should be iterating and rendering to HTML rows actually exists and is populated, but no rows are shown.
Why?
Edit
I tried not modifying the scope:
app.controller('SignUpController', function ($scope,$http) {
$scope.users = []
$scope.queryUsers = function() {
console.log("I'm being triggered")
$http.get("/existingUsers").
success(function (data,status,headers,config) {
console.log(data)
$scope.users = data
console.log($scope.users)
}).
error(function (data,status, headers, config) {
console.log(status)
})
}
})
<div class="tab-pane" id="usecase11" ng-controller="SignUpController">
<h3>Colaboradores</h3>
<div class="row">
<div class="col-sm-6">
<table class="table table-bordered">
<th ng-repeat="th in ['mail','Administrador','Miembro desde']">{{th}}</th>
<tr ng-repeat="p in users">
<td>{{p._id}}</td>
<td>{{p.mail}}</td>
<td>{{p.admin}}</td>
<td style="border:none;"><a class="close" ng-click="">$</a></td>
<td style="border:none;"><a class="close" ng-click="">*</a></td>
</tr>
</table>
</div>
</div>
</div>
However, again I can see such array printed at browser console but nothing rendered to HTML
Here is the evidence that queryUsers is being called and that $scope.users is getting something after it.
Something interesting is that I got: {{users}} right after the table and it's displaying an empty array.
Just in case this is the GET handling server code:
app.get('/existingUsers',function (request, response) {
membersCollection.find({},{"password":0}, function (err, data) {
if (err) response.send(404)
else {
data.toArray(function (err, docs) {
if (err) {
console.log(error)
response.send("Error")
}
response.send(JSON.stringify(docs, null, 4))
})
}
})
}
You don't modify the $scope. Here is the corrected code:
app.controller('SignUpController',function ($scope, $http) {
$scope.users = []
$scope.queryUsers = function() {
console.log("I'm being triggered")
$http.get("/existingUsers").
success(function (data,status,headers,config) {
console.log(data)
$scope.users = data
console.log($scope.users)
}).
error(function (data,status, headers, config) {
console.log(status)
})
}
})
HTML:
<table class="table table-bordered">
<th ng-repeat="th in ['mail','Administrador','Miembro desde']">{{th}}</th>
<tr ng-repeat="p in users">
<td>{{p._id}}</td>
<td>{{p.mail}}</td>
<td>{{p.admin}}</td>
</tr>
</table>

How to write an angularJs Controller to GET Rest Data from Parse.com

See solution below:
I'm trying to connect to a Parse.com Rest backend and display data from object values.
HTML (I put several angular calls to be sure to catch output):
<div ng-controller="MyController">
<p>{{item}}<p>
<p>{{items}}<p>
<p>{{item.firstName}}<p>
<p>{{data}}<p>
</div>
JAVASCRIPT rest:
function MyController($scope, $http) {
$scope.items = [];
$scope.getItems = function() {
$http({method : 'GET',url : 'https://api.parse.com/1/classes/Professional/id', headers: { 'X-Parse-Application-Id':'XXXX', 'X-Parse-REST-API-Key':'YYYY'}})
.success(function(data, status) {
$scope.items = data;
})
.error(function(data, status) {
alert("Error");
});
};
}
This won't work, it does strictly nothing, not even a message in the console.
I know the rest call got the correct credential, as I'm able to get object content returned when I test it with a rest tester program. Maybe the URL should not be absolute ?
Any clue is very welcome, i've spent DAYS on that.
SOLUTION:
Thanks to the help of people answering this thread, I was able to find the solution to this problem so I just wanted to contribute back:
Get Json object data from Parse.com backend, pass it authentification parameters:
function MyController($scope, $http) {
$scope.items = [];
$scope.getItems = function() {
$http({method : 'GET',url : 'https://api.parse.com/1/classes/Professional', headers: { 'X-Parse-Application-Id':'XXX', 'X-Parse-REST-API-Key':'YYY'}})
.success(function(data, status) {
$scope.items = data;
})
.error(function(data, status) {
alert("Error");
});
};
Notice that ' ' necessary arround header key object values. Those ' ' are not necessary around method and url keys.
Template that list all 'firstName' of each object:
<div ng-controller="MyController" ng-init="getItems()">
<ul>
<li ng-repeat="item in items.results"> {{item.firstName}} </li>
</ul>
</div>
Notice: "item in items.results". "results" is necessary because the return value is a JSON object that contains a results field with a JSON array that lists the objects. This could save you some headache.
Also notice "ng-init": if you don't put that, or any other form of call to the getItem(),then nothing will happen and you will be returned no error.
That was my first try of Angularjs, and i'm already in love ^^.
Based in your request the controller should be:
HTML
<div ng-controller="MyController">
<button type="button" ng-click="getItems()">Get Items</button>
<ul>
<li ng-repeat="item in items"> item.firstName </li>
</ul>
</div>
JS
function MyController($scope, $http) {
$scope.items = []
$scope.getItems = function() {
$http({method : 'GET',url : 'https://api.parse.com/1/classes/Users', headers: { 'X-Parse-Application-Id':'XXXXXXXXXXXXX', 'X-Parse-REST-API-Key':'YYYYYYYYYYYYY'}})
.success(function(data, status) {
$scope.items = data;
})
.error(function(data, status) {
alert("Error");
})
}
}
Just a little update to the newer versions of Angular (using .then since version 1.5):
myApp.controller('MyController', function($scope, $http) {
$scope.items = []
$http({
method: 'GET',
url: 'https://api.parse.com/1/classes/Users',
headers: {'X-Parse-Application-Id':'XXXXXXXXXXXXX', 'X-Parse-REST-API-Key':'YYYYYYYYYYYYY'}
})
.then(function successCallback(response) {
alert("Succesfully connected to the API");
$scope.items = data;
}, function errorCallback(response) {
alert("Error connecting to API");
});
});
var app = angular.module("app",[]);
app.controller("postcontroller", function($scope, $http){
$scope.getAllProjects = function() {
var url = 'https://reqres.in/api/products';
$http.get(url).then(
function(response) {
$scope.projects = response.data.data;
},
function error(response) {
$scope.postResultMessage = "Error with status: "
+ response.statusText;
});
}
$scope.getAllProjects();
});
<div ng-app="app">
<div ng-controller="postcontroller">
<div class="panel-body">
<div class="form-group">
<label class="control-label col-sm-2" for="project">Project:</label>
<div class="col-sm-5">
<select id="projectSelector" class="form-control">
<option id="id" ng-repeat="project in projects"
value="{{project.id}}">{{project.name}}</option>
</select>
</div>
</div>
</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>

Categories