Eve-Sama
Eve-Sama

Reputation: 2658

How to set Ionic's LocalStorage as synchronization?

Here's what I want: When I send a net request, hoping the intercept can add headers automatically.

So I made an intercept to realize the goal. I plan to get value by LocalStorage. Howerer the way of it's executive is asynchronous, so the request can't catch up with the storage.

What should I do next?

My code as belows:

intercept(req: HttpRequest<any>, next: HttpHandler):
   Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
    console.log('into intercept');
    let url = req.url;
    let opuser;
    this.storage.get('userInfo').then((val) => {
        opuser = val.Noid; // get the value what I need
    });

    if (opuser === undefined) {
        opuser = 'undefined';
    }
    const newReq = req.clone({
        url: url
    }).clone({
        setHeaders: { opuser: 'undefined' }
    });// set the headers
    return next.handle(newReq).pipe(
        mergeMap((event: any) => {
            return of(event);
        })
    );
}

Upvotes: 1

Views: 456

Answers (1)

Andrew Radulescu
Andrew Radulescu

Reputation: 1899

You should prepare your header before the interceptor will be called.

Good option:

When your application starts, get the header and store it in a provider. This way you will have synchronous/direct access to it.

opUserHeader: any;

setOpuserHeader(){
   return this.storage.get('userInfo').then((val) => {
      this.opUserHeader = val.Noid; // get the value what I need
   });
}

getOpuserHeader(){
   return this.opUserHeader ? this.opUserHeader : 'undefined';
}

and when you start the app, you can call the method from your service in app.component.ts or in the first page(your choice), and your header value will exist in memory:

headersService.setOpuserHeader().then(() => { console.log('Header is set')};

now the interceptor should look very clean and you can directly get the value:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Get the header from service, attach to the cloned request and continue
    const opUserHeader = this.headersService.getOpuserHeader();
    const authReq = req.clone({setHeaders: {opuser: opUserHeader}});
    return next.handle(authReq);

}

Bad Option:

You can put your existing code in the localStorage promise and get the value from it for all requests but performance will be affected.

Edit for Part 2:

You don't really need the address inside the interceptor function but you should call the POST method with the correct qualifier.

A complex option can be to override the HttpClient and concatenate your address to all the methods(if you don't change the endpoint) or the easiest and most sustainable in your case would be to save the address in a service and require it everytime you need like so:

apiURL = 'http://120.XXX.XXX.XXX:81/';

getApiURL(){
     return this.apiURL;
}

and everytime you call the HttpClient:

const apiURL = myService.getApiURL();
this.httpClient.post(apiURL + 'api/login', params);

Good luck!

Upvotes: 1

Related Questions