2
votes

I'm trying to use Nativescript code sharing between web and mobile with Angular and I installed latest stable version etc.. But a lot of npm modules like for example :"nativescript-localstorage" when I start using it it gives me: "Can't resolve 'tns-core-modules/file-system/file-system-access'" even after the module author tested it few hours after updating his module etc.. but for me it's not working

4

4 Answers

4
votes

I had the same issue. So I have made a service which is a wrapper of native localStorage.

After that, I inject my wrapper in my web app module and in my mobile app module. But for the mobile app module, I inject nativescript-localstorage instead of my wrapper.

Like my wrapper have the same functions than the nativescript-localstorage class, Angular see only the fire and I can use my wrapper to deal with localStorage in mobile and web!

In reality, when it's in web context, Angular use the 'native' localStorage and when it's in a mobile context, Angular use the nativescript-localstorage lib.

Below my code.

My service wrapper:

import { Injectable } from "@angular/core";

@Injectable()
export  class CustomStorageService {    
    setItem(key, value){
        localStorage.setItem(key, value);
    }

    getItem(key){
        return localStorage.getItem(key);
    }

    removeItem(key){
        localStorage.removeItem(key);
    }

    clear(){
        localStorage.clear();
    }
}

In app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { CustomStorageService } from './commons/core/services/guard/custom-storage.service';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    CustomStorageService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

My app.module.tns.ts:

import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { NativeScriptModule } from 'nativescript-angular/nativescript.module';
import { NativeScriptHttpClientModule } from 'nativescript-angular/http-client';
import * as mobileStorage from 'nativescript-localstorage';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    NativeScriptModule,
    AppRoutingModule,
    NativeScriptHttpClientModule,
    NativeScriptFormsModule
  ],
  providers: [
    {
      provide: CustomStorageService,
      useValue: mobileStorage 
    }
  ],
  bootstrap: [AppComponent],
  schemas: [NO_ERRORS_SCHEMA]
})

export class AppModule { }

An example of wrapper's usage:

import { Injectable } from '@angular/core';
import { CustomStorageService } from './custom-storage.service';

@Injectable()
export  class TokenService {
    constructor(private storage: CustomStorageService){

    }

    getToken(): String {
        return this.storage.getItem('token');
    }

    saveToken(token: String) {
        this.storage.setItem('token',token);
    }

    destroyToken() {
        this.storage.removeItem('token');
    }

    destroyAll(){
        this.storage.removeItem('token');
        this.storage.removeItem('user_id');
        this.storage.removeItem('user_name');
        this.storage.removeItem('full_name');
    }

    destroyUser() {
        this.storage.removeItem( 'currentUser' );
    }

    cleanLocalStorage() {
        this.storage.clear();
    }

}

Hope it will help.

1
votes

You can use nativescript-localstorage but keep in mind that this is a plugin that will work in a mobile environment (iOS and Android) and not in a web project. That said when you create your code shared project (between Web and NativeScript) you should create logic that uses the plugin only in the NativeScript files.

For example, create files that name ends with .tns and ad the logic for the plugin there.

home.component.ts // web file
home.component.tns.ts // NativeScript file

Full POC app demonstrating the above and using nativescript-localstorage can be found here. To test the project on a mobile device/emulator run

tns run android --bundle

to test with Angular Web project run

ng serve -o
1
votes

The answer from Neau Adrien really worked for me, do not forget to still import CustomStorageService on your module.tns.ts file

import { CustomStorageService } from './services/customstorage.service'
0
votes

You can use the dependency injection feature to provide the appropriate storage implementation in your modules:

app.module.ts (web):

providers: [    
    {
      provide: Storage,
      useValue: localStorage
    }
  ]

app.module.tns.ts (mobile):

  import * as mobileLocalStorage from 'nativescript-localstorage';

  providers: [    
        {
          provide: Storage,
          useValue: mobileLocalStorage
        }
      ]

With the above setup, you can inject the Storage in your services and components and Angular will provide the correct implementation at run-time.

export class AuthenticationService {

    constructor(private localStorage: Storage) {
    }
}