The Angular2 Http request isn't being triggered

Context :

After following multiple tutorials, I have been experimenting with authentication in Angular2 using JWT. I have created a component and a service named:

app.component.ts
user.service.ts

The app component (along with its template) contains a subscription to an observable that displays the user's logged-in status. The Observable item is stored in the user service and updates correctly when the user logs in or out.

The authentication token is stored in "localStorage" as "auth_token," which includes a time-based validity value that requires the user to log in again after a certain period.

My goal is to VERIFY the token validity upon app initialization. Initially, I attempted to do this in the user.service constructor without success. Then, I tried in the ngOnInit of the app.component, followed by an event call from the app component (button click), but encountered failures each time!

Some code snippets :

//app.component.html
//...
    <a md-button class="app-icon-button" aria-label="checklogin" (click)="checkLogin()">
        <md-icon svgIcon="check"></md-icon>
    </a>
//...

//app.component.ts
//...
    checkLogin(){
        console.log('CHECK LOGIN FUNCTION');
        let token = localStorage.getItem('auth_token');
        if(token){
            console.log('TOKEN FOUND');
            this.userService.checkToken(token);
        }else{
            console.log('NO TOKEN FOUND');
        }
    }
//...

//user.service.ts
//...
    checkToken(token){
        console.log('CHECK TOKEN FUNCTION');
        console.log('TOKEN : '+token);
        let headers = new Headers();
        headers.append('Content-Type','application/json');
        return this.http
            .post(
                '/url/script.php',
                JSON.stringify(token),
                { headers }
            )
            .map(res => res.json())
            .map((res) => {
                console.log('SCRIPT RESULT : ');
                if(res.valid){
                    console.log('TOKEN IS VALID');
                    return true;
                }else{
                    console.log('TOKEN NOT VALID');
                    return false;
                }
            });
    }
//...

I have omitted the part about observables and subscriptions.

Problem :

The main issue is that the app NEVER CALLS the script!

Whenever I click on the "checkLogin" button (with a valid token),

Console displays 'CHECK LOGIN FUNCTION',
Console displays 'TOKEN FOUND',
Console displays 'CHECK TOKEN FUNCTION',
Console displays 'TOKEN : '****************************** (token),

However, it never shows 'SCRIPT RESULT', and upon checking with Firebug for the HTTP calls, there seems to be NO CALL to the script.php. It appears that the this.http part is being ignored...

Thank you for reading/help

Answer №1

Operation commences once a user subscribes to the output data using the .subscribe method.

To initiate, use:

this.userService.checkToken(token).subscribe()

Answer №2

The validateToken() function in your codebase is sending back an Observable that you must subscribe to in order for it to run. Remember, observables won't execute unless they are subscribed to.

verifyLogin(){
        console.log('VERIFYING LOGIN STATUS');
        let token = localStorage.getItem('auth_token');
        if(token){
            console.log('TOKEN VALIDATED');
            this.userService.validateToken(token).subscribe(result => {
               console.log(result); 
            }),
            error => { 
               console.log(error); 
            });
        } else {
            console.log('NO VALID TOKEN FOUND');
        }
    }

Answer №3

You must have a subscriber in order for Ajax calls that use Observables to work correctly.

Ensure that you subscribe to the Observable, as this is a feature specific to Angular 2. Failing to subscribe will result in the call not being made at all.

Additionally, there is no need to return anything from the subscriber, as it is not possible to do so.

this.userService.verifyToken(token).subscribe((res) => {
   console.log('VERIFICATION RESULT: ');
   if(res.valid) {
      console.log('TOKEN IS VALID');          
   } else {
      console.log('TOKEN NOT VALID');
   }
});

verifyToken(token){
   console.log('VERIFY TOKEN FUNCTION');
   console.log('TOKEN : '+token);
   let headers = new Headers();
   headers.append('Content-Type','application/json');
   return this.http
       .post(
           '/url/script.php',
           JSON.stringify(token),
           { headers }
       )
       .map(res => res.json());           
}

Answer №4

Did you try utilizing Postman to invoke the necessary function?

Furthermore, what is the purpose of validating a token when angular2-jwt has that capability?

You can easily achieve this by:

Installing angular2-jwt with npm.

Include in app.module.ts:

import { AUTH_PROVIDERS } from 'angular2-jwt';

Add to providers:

providers: [
    AUTH_PROVIDERS,
],

For instance, your auth.service.ts might look like this:

import { Injectable, Inject }                                               from '@angular/core';
import { Http, Response, Headers, RequestOptions, RequestMethod }           from '@angular/http';
import { Router }                                                           from '@angular/router';

import { Observable }                                                       from 'rxjs/Observable';
import { Configuration }                                                    from '../../app.config';

import { RegisterViewModel }                                                from '../../model/viewModel/registerViewModel';
import { LoginViewModel }                                                   from '../../model/viewModel/loginViewModel';

import { tokenNotExpired, AuthHttp }                                        from 'angular2-jwt';

@Injectable()
export class AuthService {

private actionUrl: string; 

constructor(private _http: Http, private _config: Configuration, private _router: Router, private _authHttp: AuthHttp){
    this.actionUrl = _config.apiUrl;
}

register(user: RegisterViewModel){
    let headers = new Headers({ 'Content-Type': 'application/json' });
    //Admin in this system can only register users. that is why auth
    return this._authHttp.post(this.actionUrl + '/Account/Register', JSON.stringify(user), { headers : headers })
        .do(response => {
            console.log(response.toString());
        });
}
...

}

Also, keep in mind that angular2-jwt has a default token name in localstorage as id_token, unless you specify otherwise using the angular2-jwt helper class.

You can test if it's functioning correctly by simply doing this:

In app.component.ts:

export class AppComponent { 
constructor(private _auth: AuthService){
}
}

And in app.component.html:

<li>
 <a class="nav-link" [routerLink]="['/login']" *ngIf="!_auth.isAuthenticated()">Login</a>
 </li>
 <li>
 <a class="nav-link" (click)="_auth.logout()" *ngIf="_auth.isAuthenticated()">Log Out</a>
 </li>

Additionally, for further reference, you can explore the documentation at:

https://auth0.com/blog/introducing-angular2-jwt-a-library-for-angular2-authentication/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Displaying a div upon hovering over another div is resulting in numerous server requests and a flickering effect

I am attempting to create a hover effect where one div floats next to another. The layout of the divs is like a grid, placed side by side. Check out my code on this fiddle. Using plain JavaScript, I want to display a second div (div2) floating next to div ...

Tips for creating class variables with default values that are more complex than simple flat values

Creating a simple flat class like this functions smoothly: class Test { company_name: string = ""; company_id: number = 0; company_website: string = ""; } When I instantiate it with let product = new Test(), everything works as anticipated, and prod ...

Using regular expressions to enclose a JSON property value within a new string. Upgrading to MongoDB

For my testing purposes, I am attempting to transfer data from a custom JSON database to MongoDB. The data is currently stored in a json file with the following format: { "_id": "213124123114", "foo":"bar", "otherId": "2324242424", ... } To maintai ...

Connecting expressjs and angular2 for seamless communication

I find myself a little confused at the moment. I am currently in the process of developing a MEAN app and I'm wondering what the best approach is for using expressJS and Angular2 together. Is it necessary to have a view engine on the backend? Right n ...

Encountering a (500 / 503) error on the Heroku application, incorporating Laravel 5.1 and AngularJS, utilizing both GET and POST methods

My goal is to deploy my webapp on Heroku, but I've encountered a problem. Everything was working fine until I started making GET/POST requests, which resulted in a 500 or 503 error. Interestingly, the requests work locally but not on Heroku. [Note: ...

triggering Javascript upon page load

Looking to execute my Javascript only once during page load, and not during postbacks. Using Asp.net 3.5. ...

Encountering an issue with MongoDB Atlas where properties of undefined cannot be read

Hey there, I'm diving into the world of MERN Stack and working on a booking application. Currently, I'm leveraging MongoDB Atlas for my database setup and following a tutorial on YouTube to grasp the concepts. My current hurdle is connecting my ...

The title tag's ng-bind should be placed outside of the element

When using ng-bind for the title tag inside the header, it seems to produce unexpected behavior. Here is an example of the code: <title page-title ng-bind="page_title"></title> and this is the resulting output: My Page Sucks <titl ...

How can I ensure that the scrollbar stays at the bottom using CSS at all times?

I have a container with a scrollbar containing various contents, functioning as a widget. Upon initialization, I position the scrollbar at the bottom. My aim is to ensure that regardless of any changes in the parent element or its placement elsewhere, the ...

Tips for aligning an element vertically when it has a float using CSS or JavaScript

I am struggling with centering the image within the article list loop I created. The code snippet looks like this: <article class="article <?php if($i%2==0) { echo 'even'; } else { echo 'odd'; } ?>"> <section class ...

Creating Beautiful Math Equations with LaTeX in EaselJS

Can MathJAX or a similar tool be integrated into an EaselJS DisplayObject? I am looking for alternative options. I want to render text like $$ 5 + 3 - 3 = 5 $$ on a canvas that serves as an EaselJS stage. Ideally, I hope to achieve this using the Text Cl ...

Setting up bower and static files in a dotnet core project

After creating a new dotnet core project using the command dotnet new webapi, I now have the following folders and files in my project: bin controllers obj wwwroot (currently empty) dotnet.csproj Program.cs Startup.cs Now, I am lookin ...

Struggling with retrieving information from a basic JSON file using React

I am facing an issue where I need to retrieve data from a local JSON file. The following is the code snippet I am using: const myReq = new Request('./data.json') fetch(myReq) .then(rawD=> rawD.json()) .then(inf ...

Utilizing HTML and Javascript for streaming audio and recording voice

Working on a new project that involves streaming audio files (mp3) and recording voice messages. Initially considered using Flash, but the challenge is making the website iPhone-friendly as per the client's request. Is there a technology available th ...

Use JavaScript or jQuery to calculate the total value of selected radio buttons and display it in the corresponding textbox

I'm looking to calculate the sum of values from radio buttons and display that sum in the corresponding textbox using either JavaScript or jQuery. Each radio button should have a unique class name for its results. So far, I've only managed to ...

Expand external party connection

After reading a tutorial on extending interfaces in TypeScript, I learned that it's possible to extend a third-party library interface by simply defining another interface with the exact same name. The example provided in the tutorial demonstrated thi ...

Developing a unified input element containing numerous fields

After @grateful answered this question, I wanted to elaborate in case it could benefit others... In my project, there's a page called rsetup.php which has some PHP code to access a MySQL database for filling the HTML content of the page. This HTML ge ...

Turbolinks not allowing the addition of JavaScript classes for background images

While trying to merge a front end html theme with my Laravel app, I encountered an issue with turbolinks that is preventing Javascript from appending div classes. This is resulting in background images only being displayed on page refresh. <div class= ...

Invoking a function within a functional component from a React element

Let's imagine a scenario where we have a Child component that is a functional component and contains a function called a(): export default function child({ ... }) { ... function a() { ... } ... } Now, let's introduce a parent ...

Angular 6 Bootstrap Fixed Positioning

Looking to implement affix or scrollspy functionality from Bootstrap 4 into Angular 6, I've been searching for existing libraries. Came across JonnyBGod's scrollspy, but it appears to be designed for Angular 5 and uses rxjs 5. Does anyone know of ...