0

I have trying to implement auth provider for Node application which uses JWT

I'm getting error

TypeError: Cannot read property 'set' of undefined

My app.module.ts look like below.

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { LoginPage } from '../pages/login/login';

import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { HttpModule } from '@angular/http';
import { Auth } from '../providers/auth/auth';

import { Storage } from '@ionic/storage';

export function provideStorage() {
 return new Storage( { name: '__mydb' } /* optional config */);
}

@NgModule({
  declarations: [
    MyApp,
    HomePage,
    LoginPage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp),
    HttpModule,
    // IonicStorageModule.forRoot({
    //   name: '__mercury',
    //   driverOrder: ['indexeddb', 'websql']
    // })
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    LoginPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    LoginPage,
    { provide: Storage, useFactory: provideStorage },
    { provide: ErrorHandler, useClass: IonicErrorHandler },
    Auth
  ]
})
export class AppModule { }

I used documentation in https://github.com/driftyco/ionic-storage/tree/v2.0.1#configuring-storage-new-in-117

My auth.provider.ts

import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import 'rxjs';
import { Storage } from '@ionic/storage';
/*
  Generated class for the AuthProvider provider.

  See https://angular.io/docs/ts/latest/guide/dependency-injection.html
  for more info on providers and Angular 2 DI.
*/
@Injectable()
export class Auth {
  baseUrl: string = "http//localhost:9080/"

  constructor(public http: Http, public storage: Storage) {
    console.log('Hello AuthProvider Provider');
  }

  createAuthorizationHeader(headers: Headers) {
    let token;
    this.storage.get('token').then(data => token = data);
    headers.append('Athorization', token);
  }

  login(data) {
    return this.http.post('//localhost:9080/auth', data)
      .map(this.extractData);
  }

  isLogged() {
    this.storage.get('token').then(data => {
      if (data)
        return true;
      else
        return false;
    }).catch(err => {
      return false;
    });
    return false;
  }

  logout() {
    this.storage.remove('token');
    return true;

  }

  private extractData(res: Response) {
    console.log(res);
    let body = res.json();
    if (body.success === true) {

        this.storage.set("token", body.token);


    };
    return body || {};
  }
}

My platform details are

Ionic Framework: 3.2.1
Ionic Native: ^3.5.0
Ionic App Scripts: 1.3.7
Angular Core: 4.1.0
Angular Compiler CLI: 4.1.0
Node: 6.10.3
OS Platform: macOS Sierra
Navigator Platform: MacIntel
Ionic Storage : ^2.0.1
eko
  • 39,722
  • 10
  • 72
  • 98
user2473015
  • 1,392
  • 3
  • 22
  • 47
  • `IonicStorageModule.forRoot` is not working? which version of `@ionic/storage` are you using? – Suraj Rao May 24 '17 at 06:05
  • `return new Storage(['sqlite', 'websql', 'indexeddb'], { name: '__mydb' } /* optional config */);` your `new Storage` call is missing a parameter.. – Suraj Rao May 24 '17 at 06:08
  • 1
    Possible duplicate of [How to access the correct \`this\` context inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) – eko May 24 '17 at 06:10
  • @suraj it worked after changing the code according to echonax answer – user2473015 May 24 '17 at 06:35

1 Answers1

2

Change

login(data) {
    return this.http.post('//localhost:9080/auth', data)
      .map(this.extractData);
 }

to

login(data) {
    return this.http.post('//localhost:9080/auth', data)
      .map(this.extractData.bind(this));
 }

or

login(data) {
    return this.http.post('//localhost:9080/auth', data)
      .map((data)=>this.extractData(data));
 }

Your this is not refering to your component

eko
  • 39,722
  • 10
  • 72
  • 98
  • `login(data) { return this.http.post('//localhost:9080/auth', data) .map((data)=>this.extractData(data)); }` Fixed the issue – user2473015 May 24 '17 at 06:15