I'm trying to pass data from a service to a controller in angular js, the code is the following:
.controller('lista',function($scope,cetrams){
$scope.hola="This is it";
var test;
var testfn = function(){
test = 'Lala';
};
cetrams.success(function(data){
testfn();
test = data;
console.log('Inside service: '+test);
});
console.log('Inside controller: '+test);
})
The service is working, as I get the promise and the function for success is executed, but I cannot get the variable outside that function to the controller scope.
If you are expecting the value to be available at the last line
console.log('Inside controller: '+test);
then you are incorrect. Due to async nature of the code the last line would get executed before the service returns with data.
Your logic should be done in the success method or use $scope.$watch to watch the test variable for change
Related
I have build an angularjs application. there are many places I used javascript console functions.
now I want to use a single variable to turn off those console.
I dont want to check the variable everytime whenever I use the console function.
so I decided to make a service to handle that process.
Console factory
AppModule
.factory("$console", function (ENV) {
function log (txt) {
var args = arguments;
if(ENV.debug) {
console.log.apply(this, args);
}
}
...
...
});
And I called that function like the following way.
Controller
AppModule
.controller('CommonCtrl', function ($scope, $console
$scope.personalInfo = function () {
$scope.errmsg = false;
getPersonalInfo(function (data) {
if(!$scope.errmsg) {
$console.log("userdatainfo:",data);
}
...
...
})
});
All is working perfectly.
But Only the problem is I can only see the line number of the factory file on inspect panel.
I need to have the line number from where the factory function is getting called (like the line no of the above controller file).
Please reply with valuable suggestion.
This is a javascript feature and not specifically Angular. You can use arguments in a function like this. However the line number is not given but you get the caller name.
function Hello()
{
console.log("caller is " + arguments.callee.caller.toString());
}
I have some controller and a function called to obtain some value from a REST WCF web service:
fooBar.controller('fooCtrl',
function fooCtrl($scope, $http, $resource) {
$scope.someOnClickEvent = function () {
GetSomething('a','b','c');
}
}
);
function GetSomething($scope, $resource, a, b, c) {
var ServiceHandle = $resource('some/addr');
var serviceHandle = new ServiceHandle();
serviceHandle.a = a;
serviceHandle.b = b;
serviceHandle.c = c;
serviceHandle.$save().then(function (result) {
console.log('So response should be ready');
$scope.result = result.ValueFromService;
});
}
As far as I know $save() returns promise and function inside .then should be called right after response is returned by the server. In my case it's called imediately.
If service returns true I'm going to show some popup, so I need this value to be returned before conditional instruction is executed.
Version of Angular is 1.4.9.
I've analysed code and its behavior and I'm wrong obviously. Maybe I should delete this question, but I believe it can help someone to understand similar problems.
Function inside .then is in fact called after a response comes from the server. It can be verified using for instance Chrome's developer tools (namely tab network).
However if just after calling GetSomething function we want to access a $scope.result we are making a great mistake. $scope.result will be undefined as long as function inside .then won't be executed. To use a value returned from a service we must do it inside .then function or in a function called by it.
I have a controller with many functions defined on $scope.
Ex:
$scope.doSomething = function() {
}
$scope.doSomethingElse = function(data) {
}
From my doSomething function, I want to call my doSomethingElse function. Right now, I am calling it in the success function of my HTTP request (yes, it is succeeding).
Once the success function triggers, I'm calling the other function like so:
angular.scope().doSomethingElse(data); The data variable is passed through as a parameter in the success function.
After running, I'm receiving this error: TypeError: undefined is not a function
Is there another way to do this?
You can just call $scope.doSomethingElse(data); since you've already defined it as a function. As long as it is defined before you call it, this will work.
So, the important bits:
When I bind a $scope variable in my controller directly to a $resource, angular's automatic promise resolution takes over and my view gets updated as soon as data comes back from the service. However, I need to poll the server for updates on an interval. Attempting to bind to the promise returned from the $interval call is not triggering angular's automatic promise resolution and I do not know if there is something that can be done to get this $interval working against a $resource.
Angular client, ASP.NET WebApi serving JSON, Angular $resource sitting over WebApi. Inside my angular controller, if I bind a $scoped variable to my $resource promises directly, I get results; however, I need my $resources to update on an $interval and I am having problems introducing the interval.
The working, "needs manual refreshing" code (the relevant part, at least)
'use strict';
var ctrls = angular.module('MyModule',[]);
ctrls.controller('FooCtrl', ['$scope', '$location','service',
function( $scope,$location,service)
{
$scope.Bars = service.Bars;
$scope.Baz = service.Baz;
}
var app = angular.module('MyModule.Services',['ngResource']);
app.service('service', ['$resource', function($resource)
{
var proxy = $resource(
'http://server/subsystem/api/Foo/:component',
{},
{
Bars: {method:'GET',isArray:false,url: 'http://server/subsystem/api/Foo/Bars'
,Baz: {method:'GET',isArray:false,rul: 'http://server/subsystem/api/Foo/Baz'
}
return proxy;
}]);
blah blah blah, ng-repeat in my view bound to "bar in Bars" = data to screen.
So now, I go into my controller to implement my interval, and I can get the interval working but the promise does not resolve.
The changes inside the controller (note that I added $interval and $document to my dependency list:
var stop;
$scope.Bars = {};
$scope.Baz = service.Baz; //Note that angular resolves this promise automatically.
$scope.pollService = function(){
if(angular.isDefined(stop))return;
stop = $interval(function(){
if(service){
$scope.Bars = service.Bars;
}
},1000);
};
$scope.stopPolling = function(){
if(angular.isDefined(stop)){
$interval.cancel(stop);
stop = undefined;
}
};
$scope.$on('$destroy',function(){
$scope.stopPolling();
});
$document.ready(function(){
$scope.pollService(); //when I attempt to execute my .then() on pollService(), I get "cannot
//call then on undefined"
});
Edit
Note that the problem I am having is that binding $scope.Bars directly to service.Bars triggers angular's automatic promise resolution but introducing the $interval call does not seem to be. Inspecting $scope.Bars in Chrome Dev Tools indicates that it is an unresolved promise.
I updated my sample code to match what I currently have in my debugger. I have several properties defined on my resource, and I included one that I named 'Baz'. If I assign $scope.Baz = service.Baz directly within my controller, the view binds to it when angular resolves the promise but the one on the interval never does.
You aren't returning the promise from $scope.pollService. Just add return stop; at the end of your function. Also note that the way your API is written, your function will still return undefined if stop is defined.
Therefore, it should probably look like:
$scope.pollService = function(){
if(!angular.isDefined(stop)) {
stop = $interval(function() {
if(service){
$scope.Bars = service.Bars;
}
}, 1000);
}
return stop;
};
stop is also not a very good descriptive name...
EDIT:
From my understanding after reading the docs, you should be invoking the action method on the service like $scope.Bars = service.Bars();. This will return an object that will eventually get populated with data once the promise is resolved. However, I think you also need to be careful here, because if the interval fires faster than the promise resolving rate you might run into issues. I think that you would be better off using $timeout.
AngularJS latest release candidate:
I am putting a javascript object - called say stuff into the $rootScope from the module's run function, which I believe is supposed to block. This is the code:
'use strict';
/* App Module */
var app = angular.module('MyApp', ['ngRoute', 'API'])
.run(function ($rootScope, API) {
$rootScope.stuff = null;
// call the API
API.getStuff()
.success(function(data){
$rootScope.stuff = data;
})
.error(function(data){
$rootScope.stuff = null;
});
});
Now, when I attempt to access the stuff property of $rootScope from my controller, I am getting an 'undefined or null reference' error on stuff. Code looks like this:
'use strict';
app.controller('indexController',
function ($scope, $rootScope, otherAPI) {
var
stuff = $rootScope.stuff;
// call the other API
otherAPI.getDifferentStuff(stuff.property)
.success(function(data){
$scope.differentStuff = data;
})
.error(function(data){
// do some error handling stuff here
});
});
I know the api call in the run function is succeeding, and it is assigning a value to stuff in the $rootScope. Can anyone see anything obvious wrong with my code here?
Thanks for any help!
Rich
Is API.getStuff an asynchronous api call (it looks like it). In that case most likely your controller is getting initialized before the asynchronous call has returned, so $rootScope.stuff is still equal to null. If you wait until the call succeeds, then you will have your data.