Running factory based on condition - angularjs

I have a log in screen that when the user enters the correct credentials will be able to get JSON data. For now I don't have a real API link. I'm just using dummy JSON data from a script file. The loginCtrl will pass parameters to the 'dummydata' factory which will make a 'GET' request. On success, the factor will pass the JSON data to the 'useData' function in the factory. This function in the factory is what all the controllers in my ng-view use.
The problem that I am having is that all the other controllers are calling 'dummyData.dashboardsData' and getting undefined because no one has logged in to pass data to that function. How can I prevent controllers (for example, navCtrl) from calling the factory until someone has logged in?
This is my index file:
<body ng-app="ciscoImaDashboardApp" ng-style="{'background-image': backgroundImg}" ng-controller="loginCtrl">
<login></login>
<div ng-view></div>
<menu></menu>
</body>
This is my factory:
angular.module('ciscoImaDashboardApp').factory('dummyData', ['$q', '$http', function($q, $http) {
var apiServices = {};
apiServices.login = function(user,password,callback) {
$http({method: 'GET', url: 'scripts/services/dummydata.js'})
.success(function (response) {
dataStatus = response.success;
apiServices.useData(response);
callback(dataStatus);
})
.error(function(error) {
console.log("There was an error: " + error);
});
};
apiServices.useData = function(response) {
var data = response.data;
apiServices.dashboardsData = data;
}
return apiServices;
}]);
This is my navCtrl:
angular.module('ciscoImaDashboardApp')
.controller('navCtrl', function($scope, navService, $location, dummyData) {
var data = dummyData.dashboardsData;
});
This is my loginCtrl:
angular.module('ciscoImaDashboardApp')
.controller('loginCtrl', function ($scope, $rootScope, dummyData, $location) {
$scope.login = function() {
var user_email = $scope.email;
var user_password = $scope.password;
dummyData.login(user_email, user_password, function (dataStatus) {
if (dataStatus) {
console.log("Success!");
$scope.loggedIn = true;
$location.path('/welcome');
} else {
console.log("Error");
}
});
}
});

Related

Error: unable to get property 'call' of undefined or null reference

I am using AngularJs. When getting data from controller.js to service.js, I am getting the error. Below is the code used:
//controller.js
angular.module('testApp.controllers', []).
controller('testController', function ($scope, testAPIService, $timeout, $window, $location, $anchorScroll, $http) {
$scope.show = function() {
testAPIService.getDataSummary().success(function (response) {
console.log(response);
}).error(function (response) {
alert(response.responseText);
});
}
});
In Service.js
angular.module('testApp.services', []).
factory('testAPIService', ['$http', function ($http) {
var testAPIService = {};
testAPIService.getDataSummary = function () {
var request = {
url: urlBase + 'GetDataSummary',
method: 'Get',
headers: {
'accept': 'application/json'
}
}
return $http(request);
};
return testAPIService;
}]);
How to fix this? Thanks
This might be the result of including any of your app javascript file before the angularjs file.
Make sure you include angularjs file before the rest of your app files.
You're creating two different modules:
The first module testApp.controllers is created when you create the controller
Another module testApp.services is created when you create the service.
So the controller and the service are never part of the same module!
Try attaching to the same testApp module as follows:
app.js
// With [] means to create a new module.
angular.module('testApp', []);
controller.js
// Without [] means to retrieve an existing module.
angular.module('testApp').
controller('testController', function($scope, testAPIService, $timeout, $window, $location, $anchorScroll, $http) {
$scope.show = function() {
testAPIService.getDataSummary().success(function(response) {
console.log(response);
}).error(function(response) {
alert(response.responseText);
});
}
});
service.js
// Without [] means to retrieve an existing module.
angular.module('testApp').
factory('testAPIService', ['$http', function($http) {
var testAPIService = {};
testAPIService.getDataSummary = function() {
var request = {
url: urlBase + 'GetDataSummary',
method: 'Get',
headers: {
'accept': 'application/json'
}
}
return $http(request);
};
return testAPIService;
}]);
index.html
And change your ng-app directive to point to the testApp module
<html ng-app="testApp">

pass param to service from controller using typeahead in angularjs

Looking at this Plunker from an answer on SO
Plunker example
Learning angular and in the controller there is a param cityName, I am not sure how that works.
What I am trying to do is that I have a myController.js file
var app = angular.module("sampleApp");
app.controller('TypeaheadCtrl',['$scope','search', function ($scope, search) {
$scope.displayed=[];
search.getResult(searchQuery)
.then(function (data) {
$scope.displayed = (data.records);
});
}]);
myService.js
angular.module('sampleApp').factory('search', ['$q', '$http', function ($q, $http) {
var sdo = {
getResult: function (searchQuery) {
var promise = $http({
method: 'GET',
url: 'http://somewhere.com'
params: {
q: "a"
}
});
promise.success(function (data, status, headers, conf) {
return data;
});
return promise;
}
}
return sdo;
}]);
I want to be able to call the service after the third character is typed in the typeahead box and pass the characters to the service
You should use typeahead-min-length="3" option on typeahead input element.
HTML
<input type="text" ng-model="result"
typeahead="suggestion for suggestion in getSuggestion($viewValue)"
typeahead-min-length="3"/>
Then have function inside controller which will again return a promise.
$scope.getSuggestion = function (searchQuery){
return search.getResult(searchQuery)
.then(function (data) {
return data.records;
});
};
Since you have used .success the data will get return getResult function.
Use .then to chain promise so that you can return a data from the success callback.
Service
angular.module('sampleApp').factory('search', ['$q', '$http', function($q, $http) {
var sdo = {
getResult: function(searchQuery) {
var promise = $http({
method: 'GET',
url: 'http://somewhere.com'
params: {
q: searchQuery //<-- pass parameter here
}
});
promise.then(function(response) {
//you could format data here and returned formatted result
//or you could also do some sort of validation or filtering on data
return response.data;
});
return promise;
}
}
return sdo;
}]);
change your service like this
app.factory('search', ['$q', '$http', function($q, $http) {
var sdo = {};
sdo.getResult = function(query) {
var deferred = $q.defer();
var url = "http://someurlpath/api/" + query;
$http.get(url)
.success(function(data) {
deferred.resolve(data.data);
}).error(function(msg, code) {
deferred.reject(msg);
});
return deferred.promise;
};
return sdo;
}]);

undefined service response in controller to store in variable using angular?

I have a factory, calling the service and getting the response and passing in to the controller and trying to store the response in a variable which is getting undefined
app.factory('Myservice', function (service1, service2) {
return {
getService: function (data) {
service1("user", encodeURIComponent("pass")).then(function (response) {
varSessionData = response.Obj;
var queryString = strURL[1].split("&");
Service2.pageLoad(SessionData).then(function (response) {
var homeScreen = response;
data(homeScreen);
});
});
}
};
});
In Controller:
var Mydata = MyService.geService(function (data) {
Console.log(data);
return data; // getting response
});
$scope.Hello = Mydata; // undefined
Whenever you make any AJAX request they are asynchronous. That is why Angular promises are used (the .then method). So you should change your code like this in your controller:
MyService.geService(function (data) {
Console.log(data);
$scope.Hello = data;
});
Change it to the following, your data isn't defined synchronously.
Controller:
MyService.geService(function(data) {
$scope.Hello = data;
});
i have pass the $scope.Hello in Another Service controller,which means depend upon that taking the result from services.
Not working?
var HomeController = function ($scope, $rootScope, $http, $stateParams, $state, Service3, Myservice)
{
MyService.geService(function (data) {
Console.log(data);
$scope.Hello = data;
});
Not working
Service3.pageLoad($scope.Hello) // not get the value
.then(function (response) {
$scope.ServiceModelobj = response;
console.log(response);
}
Working code
var HomeController = function ($scope, $rootScope, $http, $stateParams, $state, Service3, Myservice)
{
MyService.geService(function (data) {
Console.log(data);
$scope.Hello = data;
Working//
Service3.pageLoad($scope.Hello) // get the value
.then(function (response) {
$scope.ServiceModelobj = response;
console.log(response);
});
}
}

AngularJS : returning data from service to controller

I am trying to create a service to get json and pass it to me homeCtrl I can get the data but when a pass it to my homeCtrl it always returns undefined. Im stuck.
My Service:
var myService = angular.module("xo").factory("myService", ['$http', function($http){
return{
getResponders: (function(response){
$http.get('myUrl').then(function(response){
console.log("coming from servicejs", response.data);
});
})()
};
return myService;
}
]);
My Home Controller:
var homeCtrl = angular.module("xo").controller("homeCtrl", ["$rootScope", "$scope", "$http", "myService",
function ($rootScope, $scope, $http, myService) {
$scope.goData = function(){
$scope.gotData = myService.getResponders;
};
console.log("my service is running", $scope.goData, myService);
}]);
You should return promise from getResponders function, & when it gets resolved it should return response.data from that function.
Factory
var myService = angular.module("xo").factory("myService", ['$http', function($http) {
return {
getResponders: function() {
return $http.get('myUrl')
.then(function(response) {
console.log("coming from servicejs", response.data);
//return data when promise resolved
//that would help you to continue promise chain.
return response.data;
});
}
};
}]);
Also inside your controller you should call the factory function and use .then function to get call it when the getResponders service function resolves the $http.get call and assign the data to $scope.gotData
Code
$scope.goData = function(){
myService.getResponders.then(function(data){
$scope.gotData = data;
});
};
This is an example how I did for my project, it work fine for me
var biblionum = angular.module('biblioApp', []);//your app
biblionum.service('CategorieService', function($http) {
this.getAll = function() {
return $http({
method: 'GET',
url: 'ouvrage?action=getcategorie',
// pass in data as strings
headers: {'Content-Type': 'application/x-www-form-urlencoded'} // set the headers so angular passing info as form data (not request payload)
})
.then(function(data) {
return data;
})
}
});
biblionum.controller('libraryController', function($scope,CategorieService) {
var cat = CategorieService.getAll();
cat.then(function(data) {
$scope.categories = data.data;//don't forget "this" in the service
})
});

Pass authentication error from factory to controller in AngularJS

I am trying to implement Firebase authentication via a factory and I would like to pass the error and even the authData object back to the controller from the factory. Is this possible? I can't seem to figure out how. I keep getting undefined variables.
If I print the error upon a failed login to console.log I get what should be expected, so the rest of this code works. I just can't pass the error/obj back to the controller.
My controller:
myApp.controller('LoginController', ['$scope', '$location', 'Authentication', function($scope, $location, Authentication) {
$scope.login = function() {
Authentication.login($scope.user);
// do something with error from auth factory
}
}]);
My factory:
myApp.factory('Authentication', ['$firebase', 'FIREBASE_URL', '$location', function($firebase, FIREBASE_URL, $location){
var ref = new Firebase(FIREBASE_URL);
var authObj = {
login: function(user) {
return ref.authWithPassword({
email : user.email,
password : user.password
}, function(error, authData) {
if (error) {
// pass error back to controller
// i've tried the following:
// authObj.err = error;
// return authObj.err = error;
}
else {
// pass authData back to controller
}
});
} // login
};
return authObj;
}]);
You simply pass an error handler function to the factory from the controller. Something like this (untested):
//Controller
myApp.controller('LoginController', ['$scope', '$location', 'Authentication', function($scope, $location, Authentication) {
$scope.login = function() {
Authentication.login($scope.user, function(error, authData) {
// access to error
});
}
}]);
//Factory
myApp.factory('Authentication', ['$firebase', 'FIREBASE_URL', '$location', function($firebase, FIREBASE_URL, $location){
var ref = new Firebase(FIREBASE_URL);
var authObj = {
login: function(user, errorHandler) {
return ref.authWithPassword({
email : user.email,
password : user.password
}, errorHandler);
} // login
};
return authObj;
}]);
Maybe you can do this in your controller:
$scope.login = function() {
Authentication.login(username, password).then(
function(result) {
$location.path('/stuff');
},
function(result) {
$scope.showLoginErrorMessage = true;
});
};
Note that then() takes 2 functions as parameters (one for success and one for error). This does depend on how your Authentication service works, but it looks OK to me.

Resources