0

I'm working on my first AngularJS app, I'm using Python/Flask/Rest API on the back end. I have a script inside my app.js file that does the form handling for the login. The script works as expected, but once the person logs in I want to do two things, store the JWT in localStorage, I've accomplished that.

In the same function now that I have a valid JWT, I want to run another request to give me the information for the person logged in. I am able to run the request and get valid data back but I am having trouble storing this data in a variable to use through the HTML pages. I've resorted to using $rootScope to store it and access it but I feel that this is probably not the right way and going forward I want to be sure I'm doing things correctly.

Here is my app.js code;

var app = angular.module('app', []);


app.controller('FormLoginCtrl', function ($scope, $http, $window, $rootScope) {

$scope.form = {
    email: "",
    password: "",
};
$scope.submitForm = function() {

    $http({

        url: "http://127.0.0.1:5000/auth/login_user",
        data: JSON.stringify($scope.form),
        method: 'POST',

    }).success(function(data){

        console.log("OK", data)
        localStorage.token = data.token
        sessionStorage.token = data.token

        $http({

            url: "http://127.0.0.1:5000/auth/login_user",
            method: 'GET',
            headers: {'X-API-KEY' : data.token}
        }).then(function success(response){
            console.log(response);
            $rootScope.user = response.data;
        })

    }).error(function(err){"ERR", console.log(err)})
};

});

My HTML form code;

<form name="login" ng-controller="FormLoginCtrl" ng-submit="submitForm()" id="login" class="contact-form-wrapper">

<div class="row">

    <div class="col-sm-12">

        <div class="form-group">
            <input id="inputEmail" ng-model="form.email" type="test" class="form-control" placeholder="Your Email">
            <div class="help-block with-errors"></div>
        </div>

    </div>

    <div class="col-sm-12">

            <div class="form-group">
                <input id="password" ng-model="form.password" type="text" class="form-control" placeholder="Your Password">
                <div class="help-block with-errors"></div>
            </div>

    </div>

    <div class="col-sm-12">
        <button type="submit" ng-click="Submit" class="btn btn-primary btn-sm mt-5">Login</button>
    </div>

And in my main-menu.html file where I am trying to call the variable;

<ul class="nav navbar-nav" id="responsive-menu">
    <li><a href="index.html">Write A Review</a></li>
    <li ng-hide="user"><a href="signin.html">Sign In</a></li>
    <li ng-hide="user"><a href="register.html">Register</a></li>
    <li>
    <a ng-show="user" href="category-01.html">Welcome {{ user['first_name'] }}</a>
    <ul ng-show="user">
        <li ng-show="user"><a href="agent-grid.html">My Profile</a></li>
        <li ng-show="user"><a href="agent-list.html">My Reviews</a></li>
    </ul>
    </li>
</ul>

I should add the it is currently working but I know this is probably not the proper way. I appreciate any help.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Christopher Nelson
  • 887
  • 2
  • 17
  • 26
  • 2
    Design question. You can have a service that wraps and stores the value, but ultimately it will be a global variable one way or another. You are correct that putting it on `$rootScope` is a bad idea. That means every view will have implicit access to it. You should create a service that stores it and provides controlled access to it. – Aluan Haddad Dec 30 '17 at 20:04
  • Agrre with @AluanHaddad, this is what services are for: sharing data accross controllers. – Sébastien Dec 30 '17 at 20:05
  • I'll need to read up on services as I'm not familiar. Thanks for the input. – Christopher Nelson Dec 30 '17 at 21:04

1 Answers1

1

You need to wrap your main-menu.html code in a AngularJS Controller by itself.

Once you have the data from the second API call, emit an event up the scope to the $rootScope. Along with the event send the data that you received from the API.

Then you can broadcast an event back down from the $rootScope to the other controllers in your App along with the API data.

So it'll be -

LoginController ---- emit ---> RootScope ---- broadcast ----> Other Controllers

Instead of pushing to RootScope, you might also think about having a AppController that encompasses the other controllers.

You can read more about emit, broadcast and on here - https://stackoverflow.com/a/37717690/903324

You might need this event later on for other stuff in your app.

Edit: Like others have said, you can also save the data in a service instead of sending it with the event. You can then call the service method to access the data in various controllers, but you'll still need an event to tell the other controllers in the app that the user has logged in.

Abijeet Patro
  • 2,842
  • 4
  • 37
  • 64