So I’m trying to create a custom service (called ControllerContext) for my application that makes a call to the backend to get some data that is used in multiple parts of the application. The advantage of doing it this way is that the service will run on its own and I can just make a call to it in every component that needs the data instead of having to rewrite the code to call the backend every time I need the data.
What I have so far works fine EXCEPT for if the internet connection speed is very slow. If I’m just running on my normal 5G+ speed, everything works, but if I use the network settings in edge or chrome to purposely throttle my connection down to 4G or 3G or even lower, the ControllerContext starts getting blank data. The actual call to the backend is still made and succeeds and has the right data, but when the component calls the context, it gets the wrong data.
ControllerContext:
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { getDataFromServer } from './api.service';
export interface iData {
name: string,
age: number,
job: string
}
export interface iControllerContextValue {
data: iData;
getData: () => void;
}
@Injectable({
providedIn: 'root',
})
export class ControllerContext {
private contextValue: iControllerContextValue;
private subject: Subject<iControllerContextValue> =
new Subject<iControllerContextValue>();
private contextObs: Observable<iControllerContextValue>;
constructor() {
this.contextObs = this.subject.asObservable();
this.contextValue = {
data: {
name: '',
age: 0,
job: ''
},
getData: () => {
void this.getData();
},
};
this.subject.next(this.contextValue);
void this.getData();
}
setControllerContext({
data,
}: {
data: iData;
}) {
this.contextValue = {
...this.contextValue,
data: data,
};
this.subject.next(this.contextValue);
}
getControllerContext() {
return this.contextValue;
}
getObservedControllerContext() {
return this.contextObs;
}
private async getData() {
try {
const data = await getDataFromServer();
this.setControllerContext({
data: data,
});
} catch (error) {
console.error(error);
}
}
public updateControllerContext() {
void this.getData();
}
}
The component trying to use it:
import {
ControllerContext,
iControllerContextValue,
} from 'src/app/controller-context.service';
@Component({
selector: 'user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.scss'],
})
export class UserComponent implements OnInit {
controllerContext: { context: ControllerContext; sub?: Subscription };
data: any;
constructor( controllerContext: ControllerContext) {
this.controllerContext = { context: controllerContext };
this.data = this.controllerContext.context.getControllerContext().data;
}
ngOnInit(): void {
this.controllerContext = {
...this.controllerContext,
sub: this.controllerContext.context
.getObservedControllerContext()
.subscribe((controllerContextData: iControllerContextValue) => {
this.data = controllerContextData.data;
}),
};
this.data = this.controllerContext.context.getControllerContext().data;
console.log(this.data);
}
}
When I run the code without throttling myself, the console outputs:
{
name: "testName",
age: 25,
job: "testJob"
}
But if I throttle my connection to be slow, the console outputs the default data:
{
name: "",
age: 0,
job: "",
}
This means that in slow internet connection environments, my application does not work. How do I fix this? I need my application to work in both slow and fast internet connection speeds. I would like to fix the service and not have to go back to manually calling the backend everywhere if possible. Note that ControllerContext is registered in my NgModule, I’m just trying to avoid putting the entire application here.