ZombieChowder
ZombieChowder

Reputation: 1204

Angular user JSON request from a static file

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

Answers (5)

Rohìt Jíndal
Rohìt Jíndal

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

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

Upvotes: 0

blackmiaool
blackmiaool

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

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

Upvotes: 1

Dhiraj
Dhiraj

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

Paolo
Paolo

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

Ben
Ben

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

Related Questions