1

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?

5 Answers 5

1
+50

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

What did I change?

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"
}]

Why promise?

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
Sign up to request clarification or add additional context in comments.

11 Comments

This answer is a bit irrelevant. The Authentication and Obfuscation have been removed from the example. I am looking for an exact replica of the example but using a json file as a db.
@ZombieChowder So you want the result be same with plnkr.co/edit/H4SVl6?p=preview right? Keep all the features?
yes but instead of using username === 'test' && password === 'test' to store the password, having a json file in which I could insert more usernames and passwords..
@ZombieChowder OK I see.
@ZombieChowder You want to insert more usernames and passwords by editing the json file by hand, right? Since you don't actually have a server.
|
1

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

1 Comment

thank you for your effort Paolo. This is declared within a factory and when I move it to the controller the entire thing breaks. As I've said, I am working on this example, check it out if you need additional information Example. Thank you for your help in advance.
0

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
});

2 Comments

[$injector:unpr] http://errors.angularjs.org/1.5.6/$injector/unpr?p0=<div ng-view="" class="ng-scope">copeProvider%20%3C-%20%24scope%20%3C-%20AuthenticationService This is the error message I get whenever I insert the $scope in the controller. I have already tried that. That's why I left a link to the actual example.
This error shows me that you're injecting $scope into a Service. You cannot do that in AngularJS. Try moving the logic to a Controller.
0

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.

3 Comments

this example makes sense but it doesn't work. The application freezes after the login button is clicked.
there must be some error while you are trying. I was also getting same error . Please work on it in plunker . i am able to run it in plunker.
Please find this plunker link of this example. plnkr.co/edit/RMYguZGwHvVKmA6oXJ5F?p=preview
0

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

  • What is username in your code ?
  • You should use $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);        
}]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.