I am new to AngularJS and only aware of the basics of AngularJS. I want to return a value from $http. That is $http should return a value to the global variable of My Application.
I have tried this:
var sessionValues = null;
var AdminController = angular.module('AdminController', []);
AdminController.controller('LoginController', ['$scope', '$http','$location',
function ($scope, $http, $location){
$http({
method: "post",
url: "API/MyPage.php",
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data){
sessionValues = eval(data);
console.log(sessionValues); /*Returns desired string*/
}).error(function(){
$scope.message="Some error has occured";
});
console.log(sessionValues); /*Returns null */
}
]);
I tried using $rootScope, but was not successful.
I understand that this is because it is an asynchronous call, but how can I fetch the value in JS's global variable.?
Can anyone help me about this.?
The problem is indeed with the async nature of call and when you are trying to access the variable. console.log returns null because it gets called before the $http call is complete.
Firstly we do not pollute the JavaScript global scope, but use services\factory, $rootScope to access data.
In you case if you want to expose a variable to across angular, the easiest way is to use $rootScope. Something like this
AdminController.controller('LoginController', ['$scope','$http','$location','$rootScope'
function ($scope, $http, $location,$rootScope){
$http({
method: "post",
url: "API/MyPage.php",
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function(data){
$rootScope.sessionValues = eval(data);
console.log($rootScope.sessionValues); /*Returns desired string*/
}).error(function(){
$scope.message="Some error has occured";
});
console.log($rootScope.sessionValues); /*Returns will always null due to async nature call*/
}
]);
You then have to access that variable only after it has been filled in the success call back, before that it would be always null. The console.log would always fail.
To know when the variable value has changed you can use AngularJS watch http://www.benlesh.com/2013/08/angularjs-watch-digest-and-apply-oh-my.html
I think what you want is to retrieve a constant from backend service before application loaded.
You can refer to How to retrieve constants for AngularJS from backend
In your controller, you can get the APP_CONFIG directly.
AdminController.controller('LoginController', ['$scope', '$http','$location','APP_CONFIG'
function ($scope, $http, $location, APP_CONFIG){
});
You can reuse APP_CONFIG at any angular controller, service or factory.
Related
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'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'm building an app to dynamically load and display data from a database in AngularJS, but when I try to access my API (using either $http() or $http.get()), I receive errrors.
$http.get() error: TypeError: undefined is not a function, $http() error: TypeError: object is not a function
This specific error occurs in the code to dynamically load navigation tabs.
The code for both in CoffeeScript:
p4pControllers.controller 'navCtrl', [
'$routeParams'
'$scope'
'$http'
($http,$scope,$routeParams) ->
$http(
method:'GET'
url:'http://p4p-api.snyx.nl/tables'
).success (data) ->
$scope.tabs = data
return
return
$http.get('http://p4p-api.snyx.nl/tables').success (data) ->
$scope.tabs = data
return
return
]
Does anyone see what I'm doing wrong here?
When using the array notation for injecting dependencies, the order of the arguments is important:
In your code:
['$routeParams',
'$scope',
'$http',
function ($http, $scope, $routeParams) {
// $http argument ==> $routeParams
// $scope argument ==> $scope (by coincidence)
// $routeParams argument ==> $http
}
So, basically, you are doing $routeParams.get(), but $routeParams has no method get() (nor is it a function itself).
I am working with angular js at view layer. I need to use some global variable that will be used and modified by all the controllers method in my application:
var app = angular.module('myWebservice', ['ngCookies']).run(
function($rootScope) {
$rootScope.authToken = null; });
app.controller('UserController', function($cookieStore, $scope, $location,
$routeParams, $http, $timeout, $rootScope) {
$scope.login= function() {
$http.defaults.headers.post = {'Accept' : 'application/json',
'Content-Type' : 'application/json'};
$http.post('/myServise/api/user/login-user', {
emailId : $scope.username,
password : $scope.password
}).success(function(data, status) {
if (status == 200) {
$rootScope.authToken = data.object.authToken;
}).error(function(data, status) {
console.debug(data);});
}// Else end
};// End Login
app.controller('MerchantController', function($cookieStore, $scope, $location,
$routeParams, $http, $timeout, $rootScope) {
$scope.getRootScopeValues = function()
//$scope.getRootScopeValues = function($rootScope)
{
$scope.token = $rootScope.authToken;
console.log($scope.token);// Undefined
console.log($rootScope.authToken);// Undefined
}
});
I am new to Angular JS, I have also tried to use service but I don't know why I am not able to access global variable (authToken). Please help me I am stuck at this point ....Thanks in advance...
I am not sure how your application works but looks like you have a problem of asynchronous calls (while $http is working you are trying to access the variable which is not set yet). Please look at this answer about Asynchronous calls. Maybe this is your case? Also I should note that using $rootScope is always a bad idea. Try to avoid it. You should use service instead which is also a singleton object and always a much better and maintainable approach.
I need to use some global variable that will be used and modified by all the controllers method in my application
The best way to achieve this is using a Service, but you don't have to if you would like to leave it at the $rootScope
I have tried to use service as well but same results "Undefined"
Because the call for the authToken is asynchronous, the controller could run before the token returns from remote server.
You can add the token retrieval logic to the route definition as a 'resolve' field like this:
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/your/route', {
templateUrl: 'book.html',
controller: 'BookController',
resolve: {
token: function() {
//return a promise with the token here
}
}
})
However, this is NOT good in your case as you will have to setup the 'resolve' for every route. If you are using AngularUI Route that supports nested routes, you can simply add the 'resolve' to the root state/route. This is what I've been using in my project.
If you are not using AngularUI Route, there's another way of doing it. You can assign the returned value of the $http.post to a variable in the $rootScope e.g. $rootScope.tokenPromise.
The returned of $http.post is a promise, you can use the 'then; method to register callbacks, and these callbacks will receive a single argument – an object representing the response.
In your controller, you will have put some extra lines, you will get the token asynchronously like this
app.controller('MerchantController', function($cookieStore, $scope, $location,
$routeParams, $http, $timeout, $rootScope) {
$rootScope.tokenPromise.then( function(token){
console.log(token); //depends on the returned data structure
} )
});
In your application 'run' block, you will have to create a promise at $rootScope.tokenPromise. you can either use $http to retrieve the token and get the promise there in the run block, or create a pending promise and retrieve the token elsewhere in other places, after which you can resolve the promise.
i want to share data that i get from the lastFM API between two controllers.
I've been trying with the factory but I don't get a grip on it...
angular.module('myApp')
.factory('getData', function($http, $scope, $routeParams) {
$http.get(lastfm + "&method=artist.getInfo&mbid=" + $routeParams.mbid).success(function(data) {
console.log(data)
});
})
.controller('artistCtrl', function ($scope, $routeParams, $http, getData) {
console.log(getData.data);
})
.controller('artistInfoCtrl', function ($scope, $routeParams, $http, getData) {
console.log(getData.data);
})
So how do i manage to pull this off?
There are a couple of things:
1) know that you're dealing with asynchronous data, so do not expect to be able to read the data in the controllers immediately.
2) have your factory return a function that the controllers can call. This function should return a promise that will eventually (if all goes well) be resolved with the data;
3) the controllers can call this function that is returned by the factory and in the .then() of the promise that is returned, you can actually work with the data.
My advice is to do a little research on the terms I described above, if they are not yet familiar to you. Understanding them will enable you to achieve a lot more with angular.
Your factory has no property data, you probably need to call your factory by saying
var something = getData();
and make the success handler of the $http call return that data
$http.get(lastfm + "&method=artist.getInfo&mbid=" + $routeParams.mbid).success(function(data) {
return data;
});