Reputation: 65860
On my Ionic 3 app has around 10 pages and I have implemented lazy loading feature.Now I have a question where about the Native Storage module.Do I need to import it inside the app.module.ts
file or is that ok if I'll import it each and every page's module? What is the recommended way of using it and of course the best practice?
app.module.ts
@NgModule({
declarations: [
MyApp,
],
imports: [
IonicStorageModule.forRoot(),
],
Upvotes: 4
Views: 1374
Reputation: 44659
Just like you can see in the docs, the recommended way to use the Storage is to add it to the AppModule
:
Next, add it to the imports list in your NgModule declaration (for example, in src/app/app.module.ts):
import { IonicStorageModule } from '@ionic/storage'; @NgModule({ declarations: [ // ... ], imports: [ BrowserModule, IonicModule.forRoot(MyApp), IonicStorageModule.forRoot() ], bootstrap: [IonicApp], entryComponents: [ // ... ], providers: [ // ... ] }) export class AppModule {}
And then
Finally, inject it into any of your components or pages:
import { Storage } from '@ionic/storage'; export class MyApp { constructor(private storage: Storage) { } ... // set a key/value storage.set('name', 'Max'); // Or to get a key/value pair storage.get('age').then((val) => { console.log('Your age is', val); }); }
If you don't want to do that, and prefer to add it to each page's module, a new instance of the Storage will be used for each module, but since the data is stored in the same place for the entire app, I guess the result would look like the same, but I'll recommend to add it to the AppModule
from the app.component.ts
in order to use the same instance in the entire app.
UPDATE
Just like you can see in Angular docs:
Why is a service provided in a lazy-loaded module visible only to that module?
Unlike providers of the modules loaded at launch, providers of lazy-loaded modules are module-scoped.
When the Angular router lazy-loads a module, it creates a new execution context. That context has its own injector, which is a direct child of the application injector.
The router adds the lazy module's providers and the providers of its imported modules to this child injector.
These providers are insulated from changes to application providers with the same lookup token. When the router creates a component within the lazy-loaded context, Angular prefers service instances created from these providers to the service instances of the application root injector.
This may not be so easy to see when using the Storage
, since the data is stored in the same place (storage engines underneath), but let's think that we want to inject a StatusProvider
that contains a public status: boolean
property inside of it.
Since you're working with lazy-loaded modules (and each module has its own execution context) if you include the StatusProvider
in the providers
array of the AppModule
(in the app.module.ts
file), the same instance of the StatusProvider
will be used in the entire app. So if you change the status
property somewhere in your app, and then another component from a different module tries to read the value, it will see the updated value, since the same instance is shared across the entire app.
Instead, if you add the StatusProvider
in the providers
array of each submodule, and again, since each submodule has its own execution context, each submodule will have its own copy of the StatusProvider
. Therefore if you try to modify the status
property inside of one submodule, that change won't be seen in other (lazy-loaded) submodules.
Upvotes: 2