AngularJS Defer.promise not working as expected - javascript

I'm developing an application using AngularJS & PersistenceJS.
I'm getting trouble dealing with Asynchronous calls as the
Controller :
cars.controller('CrashWidgetOneCtrl',function($scope, $location, $routeParams, CrashServices){
if($routeParams.crashId){
$scope.data = {};
console.log("CrashID: "+$routeParams.crashId);
crashId = $routeParams.crashId;
alert(1);//Works
CrashServices.getCrashDetails($scope, crashId).then(function(result){
console.log(result);
alert(2);//Never Fires
});
alert(3);//Gets executed
}else{
console.log("N");
}
});
Services :
cars.factory('CrashServices', function($http, $location, $q, CommonServices,$rootScope, $timeout){
return{
getCrashDetails:function($scope, crashId){
var deferred = $q.defer();
// Get user details if any
$scope.$apply(function(){
var crashInfoTable = App.CrashInfoTable.all();
alert(4);
crashInfoTable.list(null, function (results) {
alert(5);//This also doesn't work
deferred.resolve();
});
});
return deferred.promise;
}
}
});
Any help will be greatly appreciated. Many thanks.
Note: I am using PersistenceJS.

I dont know if you need the scope.apply.
This seemed to work for me:
getCrashDetails:function($scope, crashId){
var deferred = $q.defer();
// Get user details if any
App.CrashInfoTable.all().list(null, function(results) {
deferred.resolve(results);
});
return deferred.promise;
}

Related

AngularJS - Add function

I am just getting started with AngularJS. I'm coming from backend development, so this JavaScript is confusing for me. I followed the AngularJS tutorial and got the basics working.
I have a "record-list.component.js" file (Name derived from the AngularJS demo) which has a function to download data:
angular.module('recordList').component('recordList', {
templateUrl: 'record-list/record-list.template.html',
controller: function RecordListController($http) {
var self = this;
// self.orderProp = 'age';
$http.get('http://X/camera/record/1/').then(function(response) {
self.recordings = response.data;
});
}
})
This all works fine. However, I want to add another function that will call a URL so the backend can perform some magic. So I tried something like this:
angular.module('recordList').component('recordList', {
templateUrl: 'record-list/record-list.template.html',
controller: function RecordListController($http) {
var self = this;
// self.orderProp = 'age';
$http.get('http://blackvue.tozz.nl/camera/record/1/').then(function(response) {
self.recordings = response.data;
});
}
function DownloadFileController($file) {
$window.alert("Hi: " + $file);
}
})
This does not work. I tried a variety, such as controller: function, but nothing seems to work. Can someone point me into the good direction?
#Luiz Carlos his answer was correct! I got it working with the following code:
angular.module('recordList').component('recordList', {
templateUrl: 'record-list/record-list.template.html',
controller: function RecordListController($http) {
var self = this;
// self.orderProp = 'age';
$http.get('http://X/camera/record/1/').then(function(response) {
self.recordings = response.data;
});
this.DownloadFileController = function ($file) {
window.alert("Hi!");
}
}
})
And in HTML I can do:
<button ng-click="$ctrl.DownloadFileController()">Test</button>
Thanks!

AngularJS code hangs browser

I am calling a Web Service which returns around 3000 records as data entries as HTML response & i am trying to read this response using angularJS.
Below is my AngularJS code i am using to call the service
angular.module('tabApp', ['ngSanitize'])
.controller('TabController', ['$scope', 'HttpService', function($scope, HttpService) {
$scope.tab = 0;
$scope.setTab = function(newTab){
$scope.tab = newTab;
$scope.loading = true;
HttpService.CallService('Service.php?id='+newTab,newTab, function (data) {
$scope.myText = data;
$('.count').show();
$("[id^=searchg]").show();
$('.results').show();
});
};
$scope.isSet = function(tabNum){
return $scope.tab === tabNum;
};
$scope.setTab1 = function(newTab1){
$scope.tab = newTab1;
$('.loaderImage').hide();
};
$scope.isSet1 = function(tabNum){
return $scope.tab === tabNum;
};
}])
.service('HttpService', ['$rootScope', '$http', function ($rootScope, $http) {
$rootScope.loading = true;
return {
CallService: function (url,tabnum, callback) {
$http({
method: "POST",
url: url,
data: {id: tabnum}})
.success(function (data, status) {
$('.loaderImage').hide();
callback(data, status);
}).error(function (data, status) {
$('.loaderImage').hide();
callback(status);
});
}
}
}]);
My problem is the browser hangs if the returned records are more than 1500. Please advise on how i can improve this.
Update:
My html code looks like this
<div ng-show="isSet(1)">
<div id=matches style="display:none"></div>
<input type=text id=searchg placeholder="Type to search..." style="display:none" />
<p class="preload" ng-bind-html="myText"></p>
</div>
As we can see it is the bulky data which you are trying to bind. In Future, it could be more bulky.
You should use the server side pagination and get only the number of records, what your pagination is.
Here is the JSFiddle link for the reference.
http://jsfiddle.net/dwahlin/3Kewg/
Hope this helps! CHEERS TO CODE! :)
As #Mohit Dixit suggested, you should prefer to do server side paging and request only active page records.
I would advise you to use smart table library for this. Here is the official website for same. They support paging(both server side and client side), filter and sorting in one go.
Please note that there are many library available for this purpose but I am suggesting this as I am using it from past few years.

Angular JS Factory Variables is undefined

I have been attempting to create a script that grabs session data from a PHP API using Angular JS to create authentication.
I have created a factory called User and in my loginController I use User.Initialise() to check whether the session in PHP has a user_id attached to it.
When using User.Initialise() in my loginController (bare in mine my session has a user attached to it) it will use $location.path("/dashboard") to change the route to the dashboard. The dashboard route has a controller that has the variable $scope.UserID which is assigned using User.Session.user_id, however, when I attempt to call User.Session it returns undefined, even though User.Initialise(); assigns it in the loginController.
Can anybody shed some light on this?
var $Gladium = angular.module("Gladium", ["ngRoute", "ngAnimate", "ngSanitize"]);
$Gladium.config(function($routeProvider, $locationProvider){
$routeProvider.when("/",{
templateUrl: "pages/login.html",
controller: "loginController"
}).when("/dashboard",{
templateUrl: "pages/dashboard.html",
controller: "dashboardController"
}).when("/error/:error_code", {
templateUrl: "pages/system_error.html",
controller: "errorController"
});
});
/* Controllers */
$Gladium.controller("dashboardController", function($scope, User){
console.log("Services:");
console.log(User.Session);
});
$Gladium.controller("loginController", function($scope, $location, User){
User.Initialise().then(function(){
$scope.Authenticate = true;
if(User.loggedIn()){
$location.path("/dashboard");
}
});
/* Variables */
$scope.Email;
$scope.Password;
$scope.Login = function(){
if(User.logIn($scope.Email, $scope.Password)){
$location.path("/dashboard");
return true;
}
}
});
$Gladium.controller("errorController", function($scope, $routeParams){
$scope.Errors = {
"request": "We couldn't process that request at this time. Please try again later.",
"unknown": "An unknown error occurred if this is persistant please contact technical support."
};
$scope.currentError = $scope.Errors[$routeParams["error_code"]];
});
/* Factories */
$Gladium.factory("User", function($http, $location){
var Session;
var Error;
return {
Initialise: function(){
return $http.get("core.php?do=getSession").then(function(requestData){
if(requestData.data["requestStatus"] == 1){
Session = requestData.data.data;
}else{
$location.path("/error/request");
return false;
}
});
},
loggedIn: function(){
if(Session["user_id"] != 0){
return true;
}else{
return false;
}
},
logOut: function(){
if(Session["user_id"] != 0 ){
$http.post("core.php",{
do: "logout"
}).then(function(requestData){
if(requestData.data["requestStatus"] == 1){
}else{
}
});
}else{
console.warn("There is no user session to logout.");
}
},
logIn: function(Email, Password){
$http.post("core.php",{
do: "login",
email: Email,
password: Password
}).then(function(requestData){
if(requestData.data["requestStatus"] == 1){
Data = requestData.data;
if(Data["actionStatus"] == 1){
Initialise();
}else{
Error = Data["Error"];
return false;
}
}else{
$location.path("/error/request");
return false;
}
$location.path("/error/unknown");
return false;
});
}
}
});
I think that u just forget to return the Session variable which should be a property of User Service
....
$Gladium.factory("User", function($http, $location){
var Session;
var Error;
return {
// return the Session so it can be accessed via User.Session, or it is a variable in private closure
Session:Session
Initialise: function(){
return $http.get("core.php?do=getSession").then(function(requestData){
if(requestData.data["requestStatus"] == 1){
Session = requestData.data.data;
}else{
$location.path("/error/request");
return false;
}
});
},
....
UPDATE
Sorry the change above won't solve your problem since you are assigning the Session closure variable, which will not change User.Session.In this way it still remains undefined.
There are several ways for you to solve this problem.
One i think that is the most simple is to keep the Session private and access it via a get function User.getSession().
$Gladium.factory("User", function($http, $location){
var Session;
var Error;
return {
// use get function to get Session
getSession:function(){
return Session;
},
Initialise: function(){
return $http.get("core.php?do=getSession").then(function(requestData){
if(requestData.data["requestStatus"] == 1){
Session = requestData.data.data;
}else{
$location.path("/error/request");
return false;
}
});
},
....
In this way u can access your Session by User.getSession().

Binding issue in AngularJS

I am trying to bind from a http get request. The http get is returning true or false. I have tested the get and it is returning properly. When I run the code below, it shows the alert(1111) properly also. However, when I'm trying to change the button text, nothing appears! I have tried everything that I know to do. Any advice would be helpful.
Post.js
myApp.controller('FollowController', ['$scope', '$http', function($scope, $http) {
var status = "";
$http.get('/Home/CheckFollower?idToFollow=' + profileId + '&followerId=' + currentUserId).
success(function(data) {
//check if it is a follower
if (data) {
// Not following - Show unfollow
alert("1111");
$scope.statusMessage = data;
} else {
//Following - show Follow
$scope.statusMessage = data;
}
})
.error(function(data, status) {
console.log(data);
});
}]);
Html
<span style="float: right" ng-controller="FollowController as follow">
<button type=" button" class="btn btn-success" onclick="location.href='#Url.Action("Follow", "Home", new { idToFollow = ViewBag.ProfileId, followerId = User.Identity.GetUserId() })'">
{{ follow.statusMessage }}</button>
</span>
You should bind the variables to this instead of $scope as you are using controllerAs approach
Controller
myApp.controller('FollowController', ['$scope', '$http',
function($scope, $http) {
var status = "";
var follow = this;
$http.get('/Home/CheckFollower?idToFollow=' + profileId + '&followerId=' + currentUserId).
success(function(data) {
//check if it is a follower
if (data) {
// Not following - Show unfollow
alert("1111");
follow.statusMessage = data;
} else {
//Following - show Follow
follow.statusMessage = data;
}
})
.error(function(data, status) {
console.log(data);
});
}
]);

Scope are not updated AngularJS

I'm sad... I cook porridge of the ax..
Please, if you can - help me deal with my problem.
I have this structure in my html code(ng-controller is on wrap tag):
<a ng-repeat="subitem in cur_submenu" ng-href="#/{{subitem.href}}/">{{subitem.name}}</a>
In JS I have:
1) RouteProvider
$routeProvider.
when('/:lvl1', {
template:'<div ng-include="htmlUrl">Loading...</div>',
controller: 'MainCtrl'
})
2) Controller
function MainCtrl($scope, $http, $routeParams){
var lvl = window.location.hash.split('/');
if ($scope.submenu) {
//if data was fetch earlier, then set currentMenu
$scope.cur_submenu = $scope.submenu[lvl[1]];
} else {
MainCtrl.prototype.fetchData();
}
MainCtrl.prototype = {
fetchData: function(){
/*
* Get data about navigation
*/
$http({method: 'GET', url: 'data/main.json'}).
success(function(data){
$scope.menu = data.menu;
$scope.submenu = data.submenu;
$scope.cur_submenu = data.submenu[lvl[1]] //current submenu for my location
});
}
}
But it is not updating on my page, when I changed my location on a website(hash-nav)... Please help my. Full version of my site: http://amiu.ru
You don't need to add a function to your Controller with prototyping. Functions called in your view are to be declared on the $scope like so:
function MainCtrl($scope, $http, $routeParams){
var lvl = window.location.hash.split('/');
if ($scope.submenu) {
//if data was fetch earlier, then set currentMenu
$scope.cur_submenu = $scope.submenu[lvl[1]];
} else {
$scope.fetchData();
}
$scope.fetchData = function(){
/*
* Get data about navigation
*/
$http({method: 'GET', url: 'data/main.json'}).
success(function(data){
$scope.menu = data.menu;
$scope.submenu = data.submenu;
$scope.cur_submenu = data.submenu[lvl[1]] //current submenu for my location
});
};
}
In all other cases, if you're executing changes on a $scope outside of a $scope function, you'll need to manually call $scope.$apply() to queue a digest and update your view.

Categories