Skip to content

Commit 363920d

Browse files
refactor/AB#82357_update-angular-fix-memory-leak-issues-and-other-fixes fix: add missing subscription teardown logic and refactor in order to keep one straight susbcription for all subscriptions part 1
1 parent e17a74c commit 363920d

File tree

38 files changed

+1750
-1633
lines changed

38 files changed

+1750
-1633
lines changed

apps/back-office/src/app/app-preview/pages/form/form.component.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
GET_PAGE_BY_ID,
1818
GET_STEP_BY_ID,
1919
} from './graphql/queries';
20-
import { takeUntil } from 'rxjs/operators';
20+
import { switchMap, takeUntil } from 'rxjs/operators';
2121

2222
/**
2323
* Application preview form page component.
@@ -85,19 +85,20 @@ export class FormComponent extends UnsubscribeComponent implements OnInit {
8585
id: this.id,
8686
},
8787
})
88-
.subscribe((res) => {
89-
this.step = res.data.step;
90-
this.apollo
91-
.query<FormQueryResponse>({
88+
.pipe(
89+
switchMap((res) => {
90+
this.step = res.data.step;
91+
return this.apollo.query<FormQueryResponse>({
9292
query: GET_SHORT_FORM_BY_ID,
9393
variables: {
9494
id: this.step.content,
9595
},
96-
})
97-
.subscribe(({ data, loading }) => {
98-
this.form = data.form;
99-
this.loading = loading;
10096
});
97+
})
98+
)
99+
.subscribe(({ data, loading }) => {
100+
this.form = data.form;
101+
this.loading = loading;
101102
});
102103
} else {
103104
this.apollo
@@ -107,21 +108,22 @@ export class FormComponent extends UnsubscribeComponent implements OnInit {
107108
id: this.id,
108109
},
109110
})
110-
.subscribe((res) => {
111-
this.page = res.data.page;
112-
this.apollo
113-
.query<FormQueryResponse>({
111+
.pipe(
112+
switchMap((res) => {
113+
this.page = res.data.page;
114+
return this.apollo.query<FormQueryResponse>({
114115
query: GET_SHORT_FORM_BY_ID,
115116
variables: {
116117
id: this.page.content,
117118
},
118-
})
119-
.subscribe(({ data, loading }) => {
120-
if (data) {
121-
this.form = data.form;
122-
}
123-
this.loading = loading;
124119
});
120+
})
121+
)
122+
.subscribe(({ data, loading }) => {
123+
if (data) {
124+
this.form = data.form;
125+
}
126+
this.loading = loading;
125127
});
126128
}
127129
});

apps/back-office/src/app/app-preview/pages/workflow/workflow.component.ts

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from '@oort-front/shared';
1111
import { GET_WORKFLOW_BY_ID } from './graphql/queries';
1212
import { TranslateService } from '@ngx-translate/core';
13-
import { filter, startWith, takeUntil } from 'rxjs/operators';
13+
import { filter, startWith, switchMap, takeUntil } from 'rxjs/operators';
1414
import { SnackbarService } from '@oort-front/ui';
1515
import { PreviewService } from '../../../services/preview.service';
1616
import { Subscription } from 'rxjs';
@@ -84,47 +84,46 @@ export class WorkflowComponent extends UnsubscribeComponent implements OnInit {
8484
this.onOpenStep(0);
8585
}
8686
});
87-
this.route.params.pipe(takeUntil(this.destroy$)).subscribe((params) => {
88-
this.loading = true;
89-
this.id = params.id;
90-
this.apollo
91-
.watchQuery<WorkflowQueryResponse>({
92-
query: GET_WORKFLOW_BY_ID,
93-
variables: {
94-
id: this.id,
95-
asRole: this.role,
96-
},
97-
})
98-
.valueChanges.pipe(takeUntil(this.destroy$))
99-
.subscribe({
100-
next: ({ data, loading }) => {
101-
if (data.workflow) {
102-
this.workflow = data.workflow;
103-
this.steps = data.workflow.steps || [];
104-
this.loading = loading;
105-
if (this.steps.length > 0) {
106-
this.onOpenStep(0);
107-
}
108-
} else {
109-
this.snackBar.openSnackBar(
110-
this.translate.instant(
111-
'common.notifications.accessNotProvided',
112-
{
113-
type: this.translate
114-
.instant('common.workflow.one')
115-
.toLowerCase(),
116-
error: '',
117-
}
118-
),
119-
{ error: true }
120-
);
87+
this.route.params
88+
.pipe(
89+
switchMap((params) => {
90+
this.loading = true;
91+
this.id = params.id;
92+
return this.apollo.watchQuery<WorkflowQueryResponse>({
93+
query: GET_WORKFLOW_BY_ID,
94+
variables: {
95+
id: this.id,
96+
asRole: this.role,
97+
},
98+
}).valueChanges;
99+
}),
100+
takeUntil(this.destroy$)
101+
)
102+
.subscribe({
103+
next: ({ data, loading }) => {
104+
if (data.workflow) {
105+
this.workflow = data.workflow;
106+
this.steps = data.workflow.steps || [];
107+
this.loading = loading;
108+
if (this.steps.length > 0) {
109+
this.onOpenStep(0);
121110
}
122-
},
123-
error: (err) => {
124-
this.snackBar.openSnackBar(err.message, { error: true });
125-
},
126-
});
127-
});
111+
} else {
112+
this.snackBar.openSnackBar(
113+
this.translate.instant('common.notifications.accessNotProvided', {
114+
type: this.translate
115+
.instant('common.workflow.one')
116+
.toLowerCase(),
117+
error: '',
118+
}),
119+
{ error: true }
120+
);
121+
}
122+
},
123+
error: (err) => {
124+
this.snackBar.openSnackBar(err.message, { error: true });
125+
},
126+
});
128127
}
129128

130129
/**

apps/back-office/src/app/application/pages/form/form.component.ts

Lines changed: 55 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -85,53 +85,61 @@ export class FormComponent extends UnsubscribeComponent implements OnInit {
8585
}
8686

8787
ngOnInit(): void {
88-
this.route.params.pipe(takeUntil(this.destroy$)).subscribe((params) => {
89-
this.formActive = false;
90-
this.loading = true;
91-
this.id = params.id;
92-
this.isStep = this.router.url.includes('/workflow/');
93-
// If a query is already loading, cancel it
94-
if (this.querySubscription) {
95-
this.querySubscription.unsubscribe();
96-
}
97-
if (this.isStep) {
98-
this.querySubscription = this.apollo
99-
.query<StepQueryResponse>({
100-
query: GET_STEP_BY_ID,
101-
variables: {
102-
id: this.id,
103-
},
104-
})
105-
.pipe(
106-
switchMap(({ data }) => {
107-
this.step = data.step;
108-
return this.getFormQuery(this.step.content ?? '');
109-
})
110-
)
111-
.subscribe(({ data, loading }) => {
112-
this.handleFormQueryResponse(data, 'step');
113-
this.loading = loading;
114-
});
115-
} else {
116-
this.querySubscription = this.apollo
117-
.query<PageQueryResponse>({
118-
query: GET_PAGE_BY_ID,
119-
variables: {
120-
id: this.id,
121-
},
122-
})
123-
.pipe(
124-
switchMap(({ data }) => {
125-
this.page = data.page;
126-
return this.getFormQuery(this.page.content ?? '');
127-
})
128-
)
129-
.subscribe(({ data, loading }) => {
130-
this.handleFormQueryResponse(data, 'page');
131-
this.loading = loading;
132-
});
133-
}
134-
});
88+
this.querySubscription = this.route.params
89+
.pipe(
90+
switchMap((params) => {
91+
this.formActive = false;
92+
this.loading = true;
93+
this.id = params.id;
94+
this.isStep = this.router.url.includes('/workflow/');
95+
let currentQuery!: any;
96+
if (this.isStep) {
97+
currentQuery = this.apollo.query<StepQueryResponse>({
98+
query: GET_STEP_BY_ID,
99+
variables: {
100+
id: this.id,
101+
},
102+
});
103+
} else {
104+
currentQuery = this.apollo.query<PageQueryResponse>({
105+
query: GET_PAGE_BY_ID,
106+
variables: {
107+
id: this.id,
108+
},
109+
});
110+
}
111+
return currentQuery;
112+
}),
113+
switchMap((res: any) => {
114+
let currentFormSubscription!: any;
115+
if (this.isStep) {
116+
this.step = res.data.step;
117+
currentFormSubscription = this.getFormQuery(
118+
this.step?.content ?? ''
119+
);
120+
} else {
121+
this.page = res.data.page;
122+
currentFormSubscription = this.getFormQuery(
123+
this.page?.content ?? ''
124+
);
125+
}
126+
return currentFormSubscription;
127+
}),
128+
takeUntil(this.destroy$)
129+
)
130+
.subscribe((res: any) => {
131+
// If a query is already loading, cancel it
132+
if (this.querySubscription) {
133+
this.querySubscription.unsubscribe();
134+
}
135+
if (this.isStep) {
136+
this.handleFormQueryResponse(res.data, 'step');
137+
this.loading = res.loading;
138+
} else {
139+
this.handleFormQueryResponse(res.data, 'page');
140+
this.loading = res.loading;
141+
}
142+
});
135143
}
136144

137145
/**

apps/back-office/src/app/application/pages/settings/settings.component.ts

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ import { Dialog } from '@angular/cdk/dialog';
1313
import { DELETE_APPLICATION } from './graphql/mutations';
1414
import { Router } from '@angular/router';
1515
import { TranslateService } from '@ngx-translate/core';
16-
import { takeUntil } from 'rxjs/operators';
16+
import { filter, switchMap, takeUntil } from 'rxjs/operators';
1717
import { CustomStyleComponent } from '../../../components/custom-style/custom-style.component';
1818
import { SnackbarService, UILayoutService } from '@oort-front/ui';
19+
import { isNil } from 'lodash';
1920

2021
/**
2122
* Application settings page component.
@@ -153,51 +154,44 @@ export class SettingsComponent extends UnsubscribeComponent implements OnInit {
153154
confirmVariant: 'danger',
154155
});
155156
dialogRef.closed
156-
.pipe(takeUntil(this.destroy$))
157-
.subscribe((value: any) => {
158-
if (value) {
157+
.pipe(
158+
filter((value) => !isNil(value)),
159+
switchMap(() => {
159160
const id = this.application?.id;
160-
this.apollo
161-
.mutate<DeleteApplicationMutationResponse>({
162-
mutation: DELETE_APPLICATION,
163-
variables: {
164-
id,
165-
},
166-
})
167-
.subscribe({
168-
next: ({ errors }) => {
169-
if (errors) {
170-
this.snackBar.openSnackBar(
171-
this.translate.instant(
172-
'common.notifications.objectNotDeleted',
173-
{
174-
value: this.translate.instant(
175-
'common.application.one'
176-
),
177-
error: errors ? errors[0].message : '',
178-
}
179-
),
180-
{ error: true }
181-
);
182-
} else {
183-
this.snackBar.openSnackBar(
184-
this.translate.instant(
185-
'common.notifications.objectDeleted',
186-
{
187-
value: this.translate.instant(
188-
'common.application.one'
189-
),
190-
}
191-
)
192-
);
161+
return this.apollo.mutate<DeleteApplicationMutationResponse>({
162+
mutation: DELETE_APPLICATION,
163+
variables: {
164+
id,
165+
},
166+
});
167+
}),
168+
takeUntil(this.destroy$)
169+
)
170+
.subscribe({
171+
next: ({ errors }) => {
172+
if (errors) {
173+
this.snackBar.openSnackBar(
174+
this.translate.instant(
175+
'common.notifications.objectNotDeleted',
176+
{
177+
value: this.translate.instant('common.application.one'),
178+
error: errors ? errors[0].message : '',
193179
}
194-
},
195-
error: (err) => {
196-
this.snackBar.openSnackBar(err.message, { error: true });
197-
},
198-
});
199-
this.router.navigate(['/applications']);
200-
}
180+
),
181+
{ error: true }
182+
);
183+
} else {
184+
this.snackBar.openSnackBar(
185+
this.translate.instant('common.notifications.objectDeleted', {
186+
value: this.translate.instant('common.application.one'),
187+
})
188+
);
189+
}
190+
},
191+
error: (err) => {
192+
this.snackBar.openSnackBar(err.message, { error: true });
193+
},
194+
complete: () => this.router.navigate(['/applications']),
201195
});
202196
}
203197
}

0 commit comments

Comments
 (0)