This is the code in the controller
cat1=[];
$.getJSON('categories/1/', function(data) {
cat1 = data; //returns a JSON
});
//cat2..4 are some JSONs
$scope.pictures=[cat1,cat2,cat3,cat4,cat5];
The problem is that seems like cat1=[] and cat1=data are different variables, cause pictures[cat1] always returns []
Am I doing it wrong?
Because $.getJSON is an async request and is still processing when you try and log. Also, don't use jQuery with Angular, use Angular's $http (this way a $digest cycle is triggered and everything stays in sync):
$http.get("categories/1/").success(function(data) {
cat1 = data; //returns a JSON
$scope.pictures=[cat1,cat2,cat3,cat4,cat5];
});
Dont forget to add $http as a dependency in your controller:
app.controller("myCtrl", ["$scope", "$http", function($scope, $http) {
}]);
Related
I Have the following code in which I'm trying to get a JSON file and attach its contents to my $scope.
The first console.log returns the result that I need, but the second returns undefined.
What would be the correct way to write this so that the data is stored?
'use strict';
var myApp = angular.module('myApp.view1', ['ngRoute']);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}]);
myApp.controller('View1Ctrl', [
'$scope',
'$http',
function($scope, $http) {
$http.get('view1/info.json')
.then(function(res){
$scope.data = res.data.info
console.log($scope.data)
});
console.log($scope.data)
}]);
AngularJS's $http.get()'s then() callback is called asynchronously.
That means that in the callback, it will work, but not in the second one.
The reason for this is with something called Promises. I definitely suggets looking into them. Here is kind of what happens in order:
$http.get('view1/info.json')
That tells javascript I want to get the JSON data. But it does not actually get it yet. Then, it does that console log.
console.log($scope.data)
Well $scope.data is undefined. Nothing has set it yet! Then, javascript actually gets the JSON data. When it gets the data, the function within the then is called. After this,
$scope.data = res.data.info
console.log($scope.data)
$scope.data is defined, which is why this console.log works. Read more about promises for more info!
Here is a good starting point: https://www.youtube.com/watch?v=wA0gZnBI8i4
Well, your data is stored. But not at the time your second console.log() gets executed. The "then" promise/callback will run after your second console.log(). If you need $scope.data in your templates, this should work. Angulars digest cycle will be run after the callback of $https.
This question has been asked many times before and I've tried the answers but they do not seem to solve the problem I'm facing. I'm new to Angular and am trying to pass a value from the controller to a factory so that I can retrieve some JSON information through an API. While I'm able to get the value from my HTML to the controller, the next step is giving me a TypeError: Cannot read property 'getCityData' of undefined. My controller code is as follows:
app.controller('MainController', ['$scope', function($scope, HttpGetter) {
var successFunction = function(data) {
$scope.data = data;
}
var errorFunction = function(data) {
console.log("Something went wrong: " + data);
}
$scope.cityName = '';
$scope.getCityName = function(city) {
$scope.cityName = city;
HttpGetter.getCityData($scope.cityName, successFunction, errorFunction);
};
}]);
The factory code is as follows:
app.factory('HttpGetter', ['$http', function($http){
return {
getCityData: function(query, successFunction, errorFunction){
return $http.get('http://api.apixu.com/v1/current.json?key=MyAppKey&q=' + query).
success(successFunction).
error(errorFunction);
}
};
}]);
I've replaced my App key with the string "MyAppKey" just to be safe but my code contains the appropriate key. Also, it would be very helpful if I could get a bit of an insight on how the function invocations happen because there seem to be a lot of function callbacks happening.
Getting undefined could be because of the service not getting properly injected.
Try:
app.controller('MainController', ['$scope', 'HttpGetter', function($scope, HttpGetter)
Also as you said, to be on safer side you aren't using the right key, but anyone using your application can get the key by checking the network calls. So, ideally, one should make a call to the backend, and backend will send a call along with the secured key to the desired API endpoint and return the response data to front-end.
Can be due to ['$scope', function($scope, HttpGetter) ?
Should be ['$scope', 'HttpGetter', function($scope, HttpGetter) instead.
You used minified version and inject only $scope not HttpGetter but used as argument in controller function that's why got HttpGetter is undefiend and error shown Cannot read property 'getCityData' of undefined
So you should inject HttpGetter in your minified version ['$scope', 'HttpGetter'
use like:
app.controller('MainController', ['$scope', 'HttpGetter', function($scope, HttpGetter)
instead of
app.controller('MainController', ['$scope', function($scope, HttpGetter)
And if your MyAppKey is secured and want to hide from user then you should use it in server side
I am not able to update data in my controller using the service. I want to do an http.get in my service, do some processing on the data and then update the $scope of the controller.
I have an angular service like below. From the answers I have read in the forums my data should be updating in the view. But thats not happening.
app.service('myService', function($http, $rootScope) {
this.selected = {
item: ''
}
this.getData = function(key){
return $http.get('/myapp/stocklist/'+key);
}
this.gs = [];
this.sr = [];
this.siri=[];
var vm=this;
this.cleanData = function(response){
for( var i=0; i<response.data.length; i++ ) {
vm.gs.push(response.data[i].name);
vm.sr.push(response.data[i].high);
}
vm.siri.push(vm.sr);
}
});
and here is the controller. The gs and sr variable are blanks. From what I read I dont need to use watch for this and the code below should work(I am not very clear on how to use watch as well). If this would work with watch can you please tell me how to do it.
app.controller('graph', ['$scope', '$http', 'myService', function($scope,$http, myService) {
$scope.mySelected = myService.selected;
console.log($scope.mySelected);
myService.getData($scope.mySelected).then(function(response){
myService.cleanData(response);
$scope.sr=myService.siri;
$scope.gs=myService.gs;
console.log(myService.sr);
});
}]);
I am new to angular and also maybe structuring the code in the wrong way. I would appreciate any design suggestions as well.
I am also wondering if I am using service in the right way for $http.get. I had asked a question earlier in the forum and this is what I had got as a reply. It works when I use the returned data from the service function and do data processing in the controller itself.
Can you please help?
Looks like you're calling the myService service again to set the sr $scope after getting a response. Instead, set $scope.sr and $scope.gs to response.siri and response.gs, respectively. Updated code below:
app.controller('graph', ['$scope', '$http', 'myService', function($scope,$http, myService) {
$scope.mySelected = myService.selected;
console.log($scope.mySelected);
myService.getData($scope.mySelected).then(function(response){
$scope.cleanData = response;
$scope.sr = response.siri;
$scope.gs = response.gs;
console.log($scope.sr);
});
}]);
Sorry this works fine. I made a mistake in making the get call. Hence not giving the correct data. Thank you for your help :)
I've got an issue where I'm using the Contentful.js library to retrieve content in an Angular app. Instead of the normal $http.get with the success(data) callback, it uses a function with done(data). I can set the $scope.lists value to the returned data, but it does not show up in the HTML for some reason.
This works for a detail view using the standard $http:
$http.get('https://cdn.contentful.com/spaces/xxxxxxx/entries?sys.id=' + $routeParams.listId + '&include=10&access_token=xxxxxxxx').success (data) ->
$scope.list = data
console.log $scope.list
This doesn't work for a list view using the done() method:
client = contentful.createClient
accessToken: 'xxxxxxxx'
space: 'xxxxxxxxx'
listControllers.controller('ListListCtrl', ['$scope', '$http', ($scope, $http) ->
$scope.lists = ""
client.entries({'content_type': 'xxxxxxxx', 'include': 1}).done (data) ->
$scope.lists = data
console.log $scope.lists
])
Any ideas?
Most probably since this library is not targetted towards AngularJS, it is not doing $scope.$apply() to trigger digest cycle and hence the html is not getting updated.
The fix would be wrap the assingment done in callback with $scope.$apply().The JavaScript fix for this would be
$scope.$apply(function() {
$scope.lists = data
});
Since i have not use this library i may be wrong here with done callback implementation.
I have this plunker:
http://plnkr.co/edit/FnCTfZf8RVBx2WVscyK8?p=info
if I change the line/s(around 23)
app.controller('MainCtrl', function($scope) {
$scope.links = [...];
});
to
app.controller('MainCtrl', function ($scope, $http) {
$http.get('data.json')
.success(function(data, status, headers, config) {
$scope.links = data;
});
I don't see any data.
I guess this happens because the data is set after the ui has already been rendered.
How do I make the data binding work corectlly?
Thanks
The issue you are facing is different reference of variables.
i.e when you say
a = b
Then when you modify "b", "a" is not going to change. Hence, in ng-init you have just initialized with value
submenu = links
When "links" gets updated then "submenu" does not.
So, here you can setup watch on scope variable "links", which when updated you can update "submenu".
Please find the plunkr for the same.
Code:
$scope.$watch('links',function(newValue){
$scope.submenu=newValue;
});