Working With Authentication & Storage in Ionic

Dive In!

Two months ago I was given a project to work in a mobile app that I decided to be written in the Ionic Framework. Working with the framework was a fun experience which I found a new love and hate relationship with the Javascript ecosystem. Though I haven't delved into the specifics, learning something new is definitely the most rewarding thing out of it.

Everything should be straightforward unless you're emulating over a browser. One of those is every HTTP request is treated as a CORS request. This only applies for local development.

Take below as an example.

const headers = new HttpHeaders({'Content-Type': 'application/json'});

this.http.post(ENV.API_ENDPOINT + '/oauth/token'), {
      username: credentials.email,
      password: credentials.password,
      client_id: ENV.API_CLIENT,
      client_secret: ENV.API_SECRET,
      grant_type: 'password'
    }, {headers: headers})
    .toPromise();

Normally you would expect the request would translate as 200 POST https://domain.tld/oauth/token but instead it would request 200 OPTIONS https://domain.tld/oauth/token before doing a POST request. The solution was straightforward, setup a proxy url.

// ionic.config.json
"proxies": [
    {
      "path": "/oauth/token",
      "proxyUrl": "http://domain.local/api/oauth/token"
    }
]

Now we just need to replace URL parameter for http.post.

const uri = '/oauth/token';

this.http.post((ENV.ENVIRONMENT === 'production' ? ENV.API_ENDPOINT + uri : uri), {

After running ionic serve again everything is now running smoothly.

Async Storage?

The most frustrating part was working with the storage component. Looking through the documentation it's very straightforward enough. You only need to speciy key and value parameters to save the data. The symptom started showing when I was going to redirect the user to the HomePage.

Below is an excerpt from home.ts

this.storage.get('user').then((data) => {
  this.name = data.name;
  this.email = data.email;
}).catch(err => {
  console.log(err);
});

It took at least two pages before I data is populated. What was happening behind was interesting. Lets just assume that we're still about to authorize into the system. This makes the value of user is undefined. Now when you're successfully authorized the value of user turns null. What I expected from the start that it should contain the User object. It only returns the correct object after getting redirected over and over for at least two to three times.

The solution was to wait it out. I made a placeholder page which turned into a processing page for data syncing tasks. Then set a sleep timer for at least 3 to 5 seconds or if there are successful promises returned.

Conclusion

Coming from languages with blocking background this was my first taste in experience how asynchronous processes work. A good lesson learned while getting through a hellish language.