Reputation: 1683
I have implemented Singleton Service(i.e. ApiService) and i'm using this singleton service in the ProductCatalog Module wherein we have two methods in the singleton Service, getData()
and addData()
, which list out data and adds the data to a private data array in ApiService service.
we have two components product-listing and product-update. we use this component to list the data from the private Data variable from ApiService.
Expectation is when we use addData()
method of singleton service it should add new data to Data array and on navigating to /update should list the data from Data variable on product update component with newly add data.
Currently this is not happening whenever we add newData to data array via a addData()
Method of Single service. we are getting only the initial state of the data array without reflecting the newly added data.
Therefore, looks like i'm missing some step or implementation. please help in resolving this issue.
Here is the reference to the code. https://stackblitz.com/edit/angular-2uyx3a
Upvotes: 0
Views: 922
Reputation: 367
Ok I think you are navigating by changing the url in the browser as there is no way provided to navigate in the example provided, which surely would not work as when you change the url you are actually reloading your app, which deletes all data in your app memory.
Your service is working fine, you just need to navigate using the @angular/router, and no it can't handle manual url changes and no nothing else can do that.
But it will handle links through routerLink
more on that here - router official docs
inside product-listing.component.html
product-listing works!
<p *ngFor="let item of sampleData">{{ item.id }} -{{ item.name }}</p>
<!-- Example of using routerLink -->
<a routerLink="/update">go to update</a>
it can also handle dynamic routing through Router
service using navigateTo
or navigateByUrl
functions like this:
inside product-update.component.ts
// product-update.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router'
import { FormGroup, FormControl, FormArray } from '@angular/forms';
import { ApiService } from '../../core/api.service';
@Component({
selector: 'app-product-update',
templateUrl: './product-update.component.html',
styleUrls: ['./product-update.component.css']
})
export class ProductUpdateComponent implements OnInit {
dataForm: FormGroup;
// do not forget to import the service
constructor(private api: ApiService, private router: Router) {}
ngOnInit() {
this.dataForm = new FormGroup({
id: new FormControl(' '),
name: new FormControl(' ')
});
}
saveData() {
this.api.addData({
id: this.dataForm.controls.id.value,
name: this.dataForm.controls.name.value
});
// Use of router service `navigateByUrl` to dynamically redirect to another view
this.router.navigateByUrl('/listing')
}
}
But for any of these routing methods to work you need to add RouterModule.forChild()
to the imports of the module including these components declarations. Like this:
inside product-catalog.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import {CoreModule } from '../core/core.module';
import { RouterModule } from '@angular/router';
import { ProductListingComponent } from './product-listing/product-listing.component';
import { ProductUpdateComponent } from './product-update/product-update.component';
@NgModule({
imports: [
CommonModule, ReactiveFormsModule,
CoreModule.forRoot(),
RouterModule.forChild([]) // Add this to the imports
],
declarations: [ProductListingComponent, ProductUpdateComponent]
})
export class ProductCatalogModule { }
If you use this and test your service as it is, you will find that it is working perfectly fine.
But again when you change the url in the browser manually you are reloading your app, which deletes all of the app memory/data unless saved at backend.
Here is the link to the edit project https://stackblitz.com/edit/angular-z2m9ri
Hope this was helpful
Upvotes: 1
Reputation: 343
You don't need forRoot
in core module. You already provided the service in root:
@Injectable(
providedIn: 'root'
)
This means the service is available in the root injector of the app. The core module is useless in this context.
Here is your stackblitz code working
I recommend you take a look at Angular's documentations for more information:
Hierarchical Dependency injection
One thing to note: if you refresh the browser or change the route from browser address bar the state will get lost.
Upvotes: 1