Reputation: 1204
I am currently trying to implement this AngularJS example Tutorial Example Login but instead of having the username and password stored as strings, I am trying to extract the from a local file.
I know that this is a bad practice but that is how I am trying to do it.
In the section AngularJS Authentication Service. Path: /modules/authentication/services.js
in the example, the username and password are stored in a timeout function as:
$timeout(function(){
var response = { success: username === 'test' && password === 'test' };
if(!response.success) {
response.message = 'Username or password is incorrect';
}
callback(response);
}, 1000);
but I am trying to create a static json file which holders the username and password as objects. My idea was to make a $http.get
request to the file and append the json objects to the username and password parameters like this:
var details;
$http.get("data.json").then(function(response){
$scope.details = response.data;
console.log(username);
});
$timeout(function () {
var response = { success: username === details.username && password === details.password
if (!response.success) {
response.message = 'Username or password is incorrect';
}
callback(response);
}, 1000);
but I am getting two errors :
1.ReferenceError: $scope is not defined
2.TypeError: Cannot read property 'username' of undefined
What is the esiest way to achieve what I am trying to do? Extract the username and password from a json file and not have them as a static string?
Upvotes: 1
Views: 2095
Reputation: 27192
Observations based on the below errors :
1. ReferenceError: $scope is not defined
This error comes when we are trying to access the $scope object but forgot to inject as a dependency into the controller.
app.controller('MyCtrl', ['$scope', function ($scope) { ... }
2. TypeError: Cannot read property 'username' of undefined
username
in your code ?$scope.details.username
instead of only username
.Your code should be formatted like this :
angular.module('myApp',[]).controller('LoginController',['$scope', function ($scope) {
var details;
$http.get("data.json").then(function(response){
$scope.details = response.data;
console.log($scope.details.username);
});
$timeout(function () {
var response = { success: username === $scope.details.username && password === $scope.details.password
if (!response.success) {
response.message = 'Username or password is incorrect';
}
callback(response);
}, 1000);
}]);
Upvotes: 0
Reputation: 5344
Some snippets are from http://jasonwatmore.com/post/2014/05/26/angularjs-basic-http-authentication-example
Live demo: http://plnkr.co/edit/WvOwk1?p=preview
The original login snippet is:
service.Login = function (username, password, callback) {
$timeout(function(){
var response = { success: username === 'test' && password === 'test' };
if(!response.success) {
response.message = 'Username or password is incorrect';
}
callback(response);
}, 1000);
};
I changed it to:
var promise = $http.get("data.json").then(function (response) {
return response.data;
});
service.Login = function (username, password, callback) {
promise.then(function (data) {
var success = data.some(function (user) {
if (user.username == username && user.password == password) {
callback({
success: true
});
return true;
} else {
return false;
}
});
if (!success) {
callback({
success: false,
message: 'Username or password is incorrect'
});
}
});
};
And added a data.json:
[{
"username": "test",
"password": "test"
}, {
"username": "test2",
"password": "test2"
}]
Since you use json file as db, you should load the json file with network. And you don't need to load the data.json since it doesn't change, so you can just load it once. Using promise.then
to ensure the verification is after the $http.get
.
If you want to load the "data.json" each time the user submits the form, just replace promise.then
with
$http.get("data.json").then(function (response) {
return response.data;
}).then
Upvotes: 1
Reputation: 1462
Looking at the example , are You trying to put function for reading json file in Service method. If you are doing it then there is no $scope available in service. Hence you are getting below error
ReferenceError: $scope is not defined
In your code , there is local variable details is defined but not initialized. hence its value is undefined.
var details;
and in timeout function you are trying to access details.username
username === details.username
hence you are getting below error
TypeError: Cannot read property 'username' of undefined
But if you want to do it most easiest way then just put your code in controller like below in this plunker. you should have creates data.json file to run below code.
'use strict';
angular.module('Authentication')
.controller('LoginController',
['$scope', '$rootScope', '$location', 'AuthenticationService','$http','$timeout',
function ($scope, $rootScope, $location, AuthenticationService,$http,$timeout) {
// reset login status
AuthenticationService.ClearCredentials();
var details;
$http.get("data.json").then(function(response){
$scope.details = response.data;
//alert($scope.details.username);
});
function Login(username,password,callback){
$timeout(function(){
var response = { success: username === $scope.details.username && password === $scope.details.password };
if(!response.success) {
response.message = 'Username or password is incorrect';
}
callback(response);
}, 1000);
}
$scope.login = function () {
$scope.dataLoading = true;
Login($scope.username, $scope.password, function(response) {
if(response.success) {
AuthenticationService.SetCredentials($scope.username, $scope.password);
$location.path('/');
} else {
$scope.error = response.message;
$scope.dataLoading = false;
}
});
};
}]);
But if you want to go with same controller and make changes in service then find answer by @blackmiaool which is absolutely perfect.
What is the esiest way to achieve what I am trying to do? Extract the username and password from a json file and not have them as a static string?
The first approach is most easiest approach but it is not a standard practice.
The second approach is correct and standard approach for what you are trying to do.
Upvotes: 0
Reputation: 734
check this example:
.controller('NameOfYourController', function($scope, $http, $timeout) {
$scope.details = ""; // you can even omit the declaration here
$http.get("data.json").then(function(response){
$scope.details = response.data;
console.log($scope.details.username); // or response.data.username
$timeout(function () {
// you get to the response obj using: response.data.your_object
// $timeout logic goes here
}, 1000);
});
});
note: if you are inside a service you do not have a $scope
Upvotes: 1
Reputation: 2706
I'm not entirely sure why $scope
is undefined from your example. You're most likely not injecting it like you are with $http
or $timeout
. Another possibility is that you are trying to use $scope
in something other than a controller.
As for your second error, details
is undefined since it is set after the .then()
promise is resolved. You would want to move your $timeout
logic into that block of code like this:
var details;
$http.get("data.json").then(function(response){
$scope.details = response.data;
// ADD YOUR $timeout LOGIC HERE SO DETAILS IS NOT UNDEFINED
});
Upvotes: 0