英文:
API queries in ngOnInit are executed from previous component
问题
I have signin.component.ts
:
ngOnInit() {
this.metaService.getMetaCompany().subscribe((response: Json) => {
console.log('meta company');
});
}
and app.component.ts
:
ngOnInit() {
if (authenticated) {
this.metaService.getMetaCompany().subscribe((response: Json) => {
console.log('meta company');
});
}
}
meta.service.ts
:
getMetaCompany(): Observable<Json | JsonError> {
return this.http
.get<Json | JsonError>(this.getMetaCompanyUrl)
.pipe(
catchError(this.errorService.handleError)
);
}
app-routing.module.ts
:
...
const routes: Routes = [
{ path: 'signin', loadChildren: () => import('./signin/signin.module').then(m => m.SignInModule) },
{ path: 'inbox', loadChildren: () => import('./inbox/inbox.module').then(m => m.InboxModule) },
{ path: 'work', loadChildren: () => import('./work/work.module').then(m => m.WorkModule) },
{ path: 'something-went-wrong', component: InternalServerErrorComponent },
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.module.ts
:
...
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
BrowserAnimationsModule,
RouterModule,
AppRoutingModule
],
providers: [...],
bootstrap: [AppComponent]
})
export class AppModule { }
Redirection I execute with using these commands:
from sign out to sign in:
this.router.navigate(['signin'], { queryParams: { r: this.sharedService.currentUrl }});
from signin to another:
this.router.navigateByUrl(this.returnUrl);
When I'm on sign in page it's executed API query once, everything is fine, but after successful login I redirected to another page and in console log I see API query is executed twice: from app.component
and signin.component
.
I can't understand why I see queries from previous component (signin).
The same situation with sign out. I'm sign out and redirect to login page but API requests from ngOnInit
of any previous component (it doesn't depend on page) are executed for some reasons and I'm getting errors because user was already signed out. Everything works fine between pages/components when user was logged in.
So how can I avoid executing API queries from previous component?
英文:
I have
signin.component.ts
:
ngOnInit() {
this.metaService.getMetaCompany().subscribe((response: Json) => {
console.log('meta company');
});
}
and app.component.ts
:
ngOnInit() {
if (authenticated) {
this.metaService.getMetaCompany().subscribe((response: Json) => {
console.log('meta company');
});
}
}
meta.service.ts
:
getMetaCompany(): Observable<Json | JsonError> {
return this.http
.get<Json | JsonError>(this.getMetaCompanyUrl)
.pipe(
catchError(this.errorService.handleError)
);
}
app-routing.module.ts
:
...
const routes: Routes = [
{ path: 'signin', loadChildren: () => import('./signin/signin.module').then(m => m.SignInModule) },
{ path: 'inbox', loadChildren: () => import('./inbox/inbox.module').then(m => m.InboxModule) },
{ path: 'work', loadChildren: () => import('./work/work.module').then(m => m.WorkModule) },
{ path: 'something-went-wrong', component: InternalServerErrorComponent },
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.module.ts
:
...
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
BrowserAnimationsModule,
RouterModule,
AppRoutingModule
],
providers: [...],
bootstrap: [AppComponent]
})
export class AppModule { }
Redirection I execute with using these commands:
from sign out to sign in:
this.router.navigate(['signin'], { queryParams: { r: this.sharedService.currentUrl }});
from signin to another:
this.router.navigateByUrl(this.returnUrl);
When I'm on sign in page it's executed API query once, everything is fine, but after successful login I redirected to another page and in console log I see API query is executed twice: from app.component
and signin.component
.
I can't understand why I see queries from previous component (signin).
The same situation with sign out. I'm sign out and redirect to login page but API requests from ngOnInit
of any previous component (it doesn't depend on page) are executed for some reasons and I'm getting errors because user was already signed out. Everything works fine between pages/components when user was logged in.
So how can I avoid executing API queries from previous component?
答案1
得分: 1
这被称为Api订阅的内存泄漏,
最佳实践是在导航到其他组件之前,在当前组件中销毁您的订阅。
按照以下步骤操作:
-
在构造函数之前从'rxjs/internal/Subject'中添加Subject。
destroy$: Subject<boolean> = new Subject<boolean>();
-
在每次api调用之前的订阅之前添加以下管道。
.pipe(takeUntil(this.destroy$))
-
最后,实现OnDestory钩子以销毁所有上述订阅。
ngOnDestroy(): void { this.destroy$.next(true); this.destroy$.unsubscribe(); }
英文:
This is called as Memory Leakage by Api Subscription,
The best practice is to destroy your subscription in current component before you navigate to other component.
Follow the steps to do the same.
-
Add the Subject from 'rxjs/internal/Subject' just before the constructor.
destroy$: Subject<boolean> = new Subject<boolean>();
-
Add the below pipe to every api call before subscription
.pipe(takeUntil(this.destroy$))
-
And finally implement the OnDestory hook with destroying all above subscription.
ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.unsubscribe();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论