0

For some reason I am having trouble accessing the storage service and setting storage properties with my custom auth service.

I have a login method that should hit my API, get a token, decode the token and store the user information via storage. This all works if I do this in the login promise but that seems like an anti-pattern to me.

I've imported the storage module...

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

And injected into the constructor...

constructor(private http: Http, private storage: Storage) {
    return this.http.post(this.LOGIN_URL, JSON.stringify(credentials), { headers: this.contentHeader })
      .map(this.extractData)
      .catch(this.handleError);
}

And then when I try to use it in the response from the http service...

private extractData(res: Response) {
  let body = res.json();
  this.error = null;
  this.user = body.user[0];
  this.storage.ready().then(()=>{
    this.storage.set('profile',this.user);
    this.storage.set('token',body.token);
  });
  return body || {};
}

I get the error

Cannot read property 'set' of undefined

I can't seem to find online how it should work within a service differently from within a module.

eko
  • 39,722
  • 10
  • 72
  • 98
Jordan
  • 2,393
  • 4
  • 30
  • 60

1 Answers1

0

Use a context variable for this reference. Your code should look like below:

private extractData(res: Response) {
  let body = res.json();
  let context = this;
  this.error = null;
  this.user = body.user[0];
  this.storage.ready().then(()=>{
    context.storage.set('profile',context .user);
    context.storage.set('token',body.token);
  });
  return body || {};
}
Yuvraj Patil
  • 7,944
  • 5
  • 56
  • 56
  • The arrow syntax already does the same thing. The `this` inside the `then` will refer to the same thing in the `extractData` method. Your answer is wrong. – eko Jul 13 '17 at 07:03
  • @echonax It may be possible that he (Jordan) has made a async call inside current arrow function but he had not shared the code. So my answer can be helpful for him for that scenario. – Yuvraj Patil Jul 13 '17 at 07:13
  • 1
    In that case your answer might have been correct but the problem lies within the call of the `extractData` method. It doesn't have the lexical `this`. It should've been like `.map(this.extractData.bind(this))` or `.map((res)=>this.extractData(res))`. I haven't written it as an answer because this is a duplicate question. – eko Jul 13 '17 at 07:16
  • @echonax this ended up being my issue. I got confused with how the function was being executed. I'm still wrapping my head around this es6 stuff – Jordan Jul 13 '17 at 13:28
  • 1
    @Jordan then can you please mark your question as a duplicate with the link I've provided? – eko Jul 13 '17 at 13:29