Getting JavaScript error on asynchronous postback scope function - javascript

I am getting the following error reported on angular.min.js
0x800a1391 - JavaScript runtime error: 'Error' is undefined
with the following code:
Javascipt:
function Sucess()
{
//close
}
function Save()
{
var e = document.getElementById('FormDiv');
scope = angular.element(e).scope();
scope.Apply(Sucess)
}
My Angular scope function:
function RolesCtrl($scope, $http, $location)
{
$scope.Apply = function (CallBackSucess) {
var userId = getQSP('uid', decode(document.URL));
$http({
method: 'POST', url: 'MultiRole.aspx/Apply',
data: {}
}).
success(function (data, status, headers, config) {
// this callback will be called asynchronously
CallBackSucess();
$scope.f = data.d;
}).
error(function (data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
$scope.name = 'error';
})
}
}
Everything seems to be working fine until CallBackSucess() call is made which throws the error:
0x800a1391 - JavaScript runtime error: 'Error' is undefined

The CallBackSucess argument is passed to the .Apply() method. It is not passed to the .success() method - they are chained methods with separate scopes. Thus, in the .success() callback function, CallbackSucess() is not defined when you try to call it and thus you get an error.
Also, do you really mean to spell Sucess incorrectly?
FYI, I had to format your code like this in order to see what was actually going on:
function RolesCtrl($scope, $http, $location) {
$scope.Apply = function (CallBackSucess) {
var userId = getQSP('uid', decode(document.URL));
$http({
method: 'POST',
url: 'MultiRole.aspx/Apply',
data: {}
}).success(function (data, status, headers, config) {
// this callback will be called asynchronously
CallBackSucess();
$scope.f = data.d;
}).error(function (data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
$scope.name = 'error';
})
}
}

Related

Test an Angular service by expecting a function call: Jasmine createSpy

I have a controller that calls a service function, by passing in 2 functions as parameters (to be called dependent on the outcome of the service function), like so:
Controller code:
onSuccess(data){ ... }
onError(data){ ... }
service.post(url, query, onSuccess, onError);
Service code:
var service = function($log, $http, $location, $interval) {
...
var post = function(url, query, onSuccess, onError){
$http.post(url, query)
.success(function(data, status, headers, config){
onSuccess(data);
})
.error(function(data, status, headers, config){
onError(data);
});
};
...
});
What I'm trying to do is test that the query passed into the post function is correct and so the onSuccess function located within the controller code is called. I've tried to test this like so:
Test code:
describe("post", inject(function (service) {
beforeEach(module('myApp'));
beforeEach(function() {
var url = "http://..."
var query = {
...
}
var mockSuccess = jasmine.createSpy('Success function');
var mockError = jasmine.createSpy('Error function');
service.post(url, query, mockSuccess, mockError);
}
it('Should call success function following call to http.post', function () {
expect(mockSuccess).toHaveBeenCalled();
});
))};
Although I'm getting the error:
TypeError: null is not an object (evaluating 'currentSpec.$modules')
So I'm not sure how to properly test whether my query is successful in returning data through the http request?
Thanks in advance.

AngularJS : Injecting Service in app.run

I want to initialize a globle variable "$rootScope.SegmentSelectedGlobal" at the starting of application only.
This globle variable get data from a service.
If i execute service through controller, its working fine.
But when i execute it from App.run, no value is being assinged an d no error is being reported.
Here is the code:
App.run :
app.run(['$rootScope','DashboardService', function($rootScope,DashboardService) {
$rootScope.SegmentSelectedGlobal = DashboardService.getSegments();
}]);
Service :
app.service("DashboardService",function($q,$http,errorMessages){
var allSegements = [];
return {
// For selected Only
getSegments : getSegments
}
function getSegments(){
var deferred = $q.defer();
$http({
url: "/getAllSegments",
method: "GET"
}).success(function (data, status, headers, config) {
deferred.resolve(data);
allSegements = data;
}).error(function (data, status, headers, config) {
//logger.logError('Error while retrieving Versions details');
allSegements = null;
});
return allSegements;
}
});
Thanx for your help.
It returns undefined because at return allSegements allSegements is undefined.
Your using a promise, yet your forgot to return it properly
app.service("DashboardService",function($q,$http,errorMessages){
var allSegements = [];
return {
// For selected Only
getSegments : getSegments
}
function getSegments(){
var deferred = $q.defer();
$http({
url: "/getAllSegments",
method: "GET"
}).success(function (data, status, headers, config) {
deferred.resolve(data);
allSegements = data;
}).error(function (data, status, headers, config) {
//logger.logError('Error while retrieving Versions details');
deferred.reject();//--------- REJECT IF ERROR
});
return deferred.promise;//------- RETURN THE PROMISE
}
});
app.run(['$rootScope','DashboardService',function($rootScope,DashboardService) {
// use then to get the data from your promise ince it's ready
DashboardService.getSegments().then(function(data){
$rootScope.SegmentSelectedGlobal = data;
});
}]);
Note if you want to wait for the promised to be resolved before loading your page, use the resolve attribute (available in both ngRoute/ui-router) :
resolve:{
segments:['DashboardService', function(DashboardService){
return DashboardService.getSegments();//we return the promise, the resolve parameter will take the result, in case of error page won't be loaded.
}];
}

how to call $scope.function1 from $scope.function2

I have a controller with the two functions.function "fileHistory" will be loaded first.
and i need to same call the same function from another function success callback.
i tried this way- but i am getting error
here is my Controller code
function cBookController($scope,$http) {
$scope.fileHistory = function() {
$http({
url: '/123/rest/getUploadDetails',
method: "GET"
})
.success(function (data, status) {
console.log(data);
$scope.fileHistory = data;
})
.error(function (data, status) {
alert("Error in get history details process");
});
}
$scope.fileHistory();
$scope.checkStatus = function(uploadedFileId) {
$http({
method: 'GET',
url: '/123/rest/checkStatus',
})
.success(function(data, status, headers, config) {
//here i need to get the new datafrom fileHistory service.
$scope.fileHistory();
})
}
}
By checking in your code I see that inside the $http success callback of fileHistory function, you override your function with response data from $http
Your fileHistory is a function at first. But after your promise is executed you are assigning this to a data variable and overriding it.
Change following line to something else -
//$scope.fileHistory = data; // change this line
$scope.fileHistoryData = data;

Angular $scope not available outside my function

Somewhat new to Angular and javascript. I have the following controller written use a factory service to access a local JSON file. Most of this code is derived (or completely taken) from this post by Dan Wahlin. I am unable to access the $scope.books variable outside of the function and cannot figure out why. The console.log inside the function gives me the object I am looking for, but the one outside returns undefined. What am I doing wrong here? Thanks.
app.controller('FormController', ['$scope', 'tocFactory', function ($scope, tocFactory) {
$scope.books;
getBooks();
function getBooks() {
tocFactory.getBooks().
success(function(data, status, headers, config) {
$scope.books = data;
console.log($scope.books);
}).
error(function(data, status, headers, config) {
// log error
})
}
console.log($scope.books);
}]);
Because you are making an ajax and then executing the next line of code. Which doesn't mean you have guarantee that your ajax response is ready on execution of next line of code.
You could always gets its response value inside the success function of $http which gets called when ajax call executed successfully.
Read here How asynchronous call works?
actually this isn't an issue of scope, but timing. The getBooks function is executed asynchronously, so when your console log happens it most likely will not have been bound to anything. You could test this easily with interval to see how this is happening:
app.controller('FormController', ['$scope', 'tocFactory', function($scope, tocFactory) {
$scope.books;
getBooks();
function getBooks() {
tocFactory.getBooks()
.success(function(data, status, headers, config) {
$scope.books = data;
console.log($scope.books);
})
.error(function(data, status, headers, config) {
// log error
})
}
setInterval(function(){
console.log($scope.books);
}, 1000);
}]);
You can use $q service to handle asynchronous code with promises :
app.controller('FormController', ['$scope', '$q', 'tocFactory', function ($scope, $q, tocFactory)
{
var getBooks = function()
{
var deferred = $q.defer();
tocFactory.getBooks().
success( function(data, status, headers, config)
{
$scope.books = data;
deferred.resolve();
} ).
error( function(data, status, headers, config)
{
deferred.reject();
} );
return deferred.promise;
};
getBooks().then( function(res)
{
console.log($scope.books); // success : your data
}, function(res)
{
console.log($scope.books); // error : undefined
} );
console.log($scope.books); // undefined
} ] );
I haven't tested this code but it should work and show you promises principle.
More about $q service : https://docs.angularjs.org/api/ng/service/$q

ngResource query returns strange objects

I am new to AngularJS and wanted to try out the $resource functionality.
I have this code:
.factory('GetTasksService', function($resource, BASE_URL) {
return $resource(BASE_URL + 'api/tasks');
})
.controller('TasksCtrl', function ($scope, $http, BASE_URL, GetTasksService) {
$scope.tasks = GetTasksService.query();
$scope.getTasks = function () {
$http({ url: BASE_URL + 'api/tasks', method: 'GET' })
.success(function (data, status, headers, config) {
$scope.tasks = data;
})
.error(function (data, status, headers, config) {
alert("call did not work");
});
}
});
The getTasks function works as expected - returning an array of:["taska", "taskb"] as it should.
The GetTasksService.query() however returns an array of [{"0":"t","1":"a","2":"s","3":"k","4":"a"}, {"0":"t","1":"a","2":"s","3":"k","4":"b"}]
Can anyone tell me what I am doing wrong?
There is an option when specifying an action for an ngResource called isArray;
The default action query sets this as true by default, so you need to set set the action like:
query : {
method : 'GET',
isArray : false
}

Categories