I have a rather simple question. I have a simple controller and its $scope.coords = []; renders JSON in HTML:
[24.43359375, 54.6611237221]
[25.2905273438, 54.6738309659]
[25.3344726562, 54.6102549816]
[25.2685546875, 54.6801830971]
[25.2960205078, 54.6611237221]
How can I render that JSON not in html, but in my controller itself ? The code looks like that. Please see the comment in code:
propertyModule.controller('propertyController', ['$scope', 'Property', function ($scope, Property) {
// Query returns an array of objects, MyModel.objects.all() by default
$scope.properties = Property.query();
// Getting a single object
$scope.property = Property.get({pk: 1});
$scope.coords = [];
$scope.properties = Property.query({}, function(data){
console.log(data);
angular.forEach(data , function(value){
$scope.coords.push(value.coordinates);
});
});
$scope.positions = //$Resource('realestate.property').items();
[
[54.6833, 25.2833], [54.67833, 25.3033] // those coordinates are hardcoded now, I want them to be rendered here by $scope.coords
];
}]);
First off, you're showing us a bunch of arrays, not a JSON document. But since your code seems to be working, I'll assume you do have a valid JSON to work with.
You need to consider the fact that you are making an asynchronous request here :
$scope.properties = Property.query({}, function(data) {
console.log(data);
angular.forEach(data , function(value){
$scope.coords.push(value.coordinates);
});
});
This means you won't be able to fetch data from $scope.coords before anything has arrived.
There are several ways to solve that :
You could simply fetch data while you're still in the loop :
angular.forEach(data , function(value) {
$scope.coords.push(value.coordinates);
if('your condition') {
$scope.positions.push(value.coordinates);
}
});
You could use a promise, see the angular doc.
Or you could watch over $scope.coords with $scope.$watch.
Related
Iam trying to create a custom filter to filter matching array of values in angularjs. Array Structure below
["tag1","tag2"]
Now I need to filter all objs having tags matching id1,id2.. Below is the filter I have tried
var autoFilter = angular.module("autoFilters",[]);
autoFilter.filter('arrayData', function (){
return function(){
return ["id1","id2"];
}
//$scope.arrayValues = ["id1","id2"];
});
and UI code below
<li style="cursor:pointer" ng-cloak class="list-group-item" ng-repeat="values in suggestionResults | arrayData">{{values.id}} -- {{values.title}}</li>
But Data is not showing up. Can you help me out where Iam doing wrong. Plunker Code available below
plunker here
see the code below :) This is not the best approach in my opinion and will definitely have some performance issue with larger lists, but it does the work (now I used indexOf(2) but there you can pass any truthy/falsy argument)
var autoFilter = angular.module("autoFilters",[]);
autoFilter.controller("filterController",['$scope','$http', function ($scope,$http) {
$scope.searchSuggest = function(){
//$http({method: 'GET', url: 'json/searchSuggestions.json'}).success(function(data) {
$http.get("assets.json").then(function(response) {
//var str = JSON.stringify(response);
//var arr = JSON.parse(str);
$scope.suggestionResult = response.data;
console.log($scope.suggestionResult);
//$scope.arrayData = ["asset_types:document/data_sheet","asset_types:document/brochure"];
}).catch(function activateError(error) {
alert('An error happened');
});
}
$scope.showProduct = function(){
}
}]);
autoFilter.filter('arrayData', function (){
return function(data){
// if you are using jQuery you can simply return $.grep(data, function(d){return d.id.indexOf('2') >-1 });
return data.filter(function(entry){
return entry.id.indexOf('2') > -1
})
}
});
Having experienced working with large lists I would, however, suggest you to avoid using a separate filter for this and rather manipulate it in the .js code. You could easily filter the data when you query it with your $http.get like:
$scope.suggestionResult = response.data.filter(function(){
return /* condition comes here */
}
This way you are not overloading the DOM and help the browser handling AngularJS's sometimes slow digest cycle.
If you need it to be dynamic (e.g. the filtering conditions can be changed by the user) then add an ng-change or $watch or ng-click to the modifiable information and on that action re-filter $scope.suggestionResult from the original response.data
I receive from my rest api news with the specified id. When I display all news I used ng-repeat and works fine but when I want display one object this method is not working.
My .when code:
.when('/displaynews/:id',{
templateUrl: 'views/display.html',
controller: 'NewsDisplayController',
constollerAs: 'displaydash'
})
and the controller:
.controller('NewsDisplayController',
function($routeParams, NewsModel){
var displaydash = this;
var newsId = $routeParams.id;
path = 'getNewsById/'+newsId;
function getNewsById() {
NewsModel.getNewsById().then(function (result){
displaydash.news = result.data;
console.log(displaydash.news);
})
}
getNewsById();
})
Result from console.log:
Object { id="56f1ba6b275c8aa5bf4895d8", title="Tytul", text="Text", more...}
How can I display this in my html template?
I try to display in html file in this way:
<p>{{news.title}}</p>
<p>{{news.text}}</p>
But it's not working
You can go for :
angular.toJson(JSONObj);
So, here you can go for:
in Controller:
displaydash.news = result.data;
$scope.news = angular.toJson(displaydash.news);
in HTML:
<p>{{news}}</p>
The issue in your question is simple, you are trying to access news object which you have not defined, try creating a scope variable for it, you will be easily able to access it:
$scope.displaydash.news = result.data;
<p>{{displaydash.news.title}}</p>
<p>{{displaydash.news.text}}</p>
Refer: https://docs.angularjs.org/api/ng/function/angular.toJson
If result.data is an object, enclose it with square brackets and set as news, otherwise use it directly.
displaydash.news = typeof(result.data) == "object"?[result.data]: result.data;
I'm trying to convert my basic crud operations into an API that multiple components of my application can use.
I have successfully converted all methods, except the update one because it calls for each property on the object to be declared before the put request can be executed.
controller
$scope.update = function(testimonial, id) {
var data = {
name: testimonial.name,
message: testimonial.message
};
dataService.update(uri, data, $scope.id).then(function(response) {
console.log('Successfully updated!');
},
function(error) {
console.log('Error updating.');
});
}
dataService
dataService.update = function(uri, data, id) {
var rest = Restangular.one(uri, id);
angular.forEach(data, function(value, key) {
// needs to be in the format below
// rest.key = data.key
});
// needs to output something like this, depending on what the data is passed
// rest.name = data.name;
// rest.message = data.message;
return rest.put();
}
I tried to describe the problem in the codes comments, but to reiterate I cannot figure out how to generate something like rest.name = data.name; without specifying the name property because the update function shouldn't need to know the object properties.
Here is what the update method looked like before I started trying to make it usable by any of my components (this works)
Testimonial.update = function(testimonial, id) {
var rest = Restangular.one('testimonials', id);
rest.name = testimonial.name;
rest.message = testimonial.message;
return rest.put();
}
How can I recreate this without any specific properties parameters hard-coded in?
Also, my project has included lo-dash, if that helps, I don't know where to start with this problem. Thanks a ton for any advice!
Try like
angular.extend(rest,testimonial)
https://docs.angularjs.org/api/ng/function/angular.extend
I am badly stuck with this problem of passing data from one controller to other in angularJS. Before my code was: whenever I click on templateController's div, it would trigger setTemplate with the help of ng-click... Now my objective was to send templateController's selected data to ReplyController...
After reading forum posts here, i decided to create a service called 'selectionService', so that i can transmit data between 2 controllers...
//Defined Service
proApp.service('selectionService', function() {
var selected_template;
addTemplate = function(newObj) {
selected_template = newObj;
};
getTemplate = function(){
return selected_template;
};
});
//Controller 1... where templates are selected
proApp.controller('TemplateController',function($scope, selectionService)
{
$scope.templates = [
{template_name:"Template 1", template_text:"We apologize for the interruption."} ,
{template_name:"Template 2", template_text:"Thank you for contacting us."} ,
} ,
];
// on ng-click
$scope.setTemplate = function(tmp)
{
selectionService.addTemplate(tmp);
}
});
// Controller 2 ... supposed to catch the selected template.
proApp.controller('ReplyController', function($scope, selectionService)
{
$scope.template = selectionService.getTemplate();
});
So whenever i run this code, i started getting this error
Object [object Object] has no method addTemplate...
Again I tweeked the code where they were suggesting to use Squarebrackets and put $scope , servicename and then write function with same parameters.. I don't understand why I should do this? Event after doing some changes like
[ '$scope' , 'service' , function($scope, service){}] ,
I am still not able to figure out the solution to pass data from one controller to other using service.
Could you help? What am I missing? I am very new to angularJS way of doing stuff.
I think it's actually quite simple. You just need to add your methods to the service by using this.. Currently they are declared on window. Change your service declaration to use this...
proApp.service('selectionService', function() {
var selected_template;
this.addTemplate = function(newObj) {
selected_template = newObj;
};
this.getTemplate = function(){
return selected_template;
};
});
As for using the array notation for dependencies, it's a good practice but it's not required. It'll save you from headaches if you ever run your code through a minifier.
I'm taking my first steps with AngularJS calling an API that would send back a JSON object with the data that I need. I calls the API and takes the response and print it on the HTML, iterating as needed.
But I haven't found a way on the actual Javascript file, to iterate to lets say, group and sum items, or to print the actual values of the JSON to the console.
app.js
angular.module('dashboard', ['ngResource']);
function DashboardCtrl($scope, $resource) {
$scope.dailyReports = $resource('http://myurl.com/app_dev.php/:action',
{action:'dailyreports', appid:'#appid', begindate:'#begindate', enddate:'#enddate'});
$scope.loadData = function() {
$scope.dailyreportsResults = $scope.dailyReports.get({appid:$('#sel-apps').val(), begindate:$('#fecha-inicial').val(), enddate:$('#fecha-final').val()});
//it works!!!!
};
$scope.iterate = function() {
for (i=0; i < $scope.dailyreportsResults.data.length; i++){
$scope.periodUnits += $scope.dailyreportsResults.data[i].units;
console.log($scope.periodUnits);
//It doesnt work :(
}
};
index.html
ng-repeat="data in dailyreportsResults.data"
{{data.countryName}}
{{data.units}}
What am I doing wrong?
Thanks guys!
I'm not sure what your data looks like, but maybe you should be using 'for in' instead of incrementing an array.
$scope.iterate = function() {
for (x in $scope.dailyreportsResults.data){
$scope.periodUnits += $scope.dailyreportsResults.data[x].units;
console.log($scope.periodUnits);
}
};
also, I think your ng-repeat should be attached to an element.
<div ng-repeat="data in dailyreportsResults.data">
{{data.countryName}}
{{data.units}}
</div>