V
V
Vladimir Denisov2017-10-01 19:50:20
JavaScript
Vladimir Denisov, 2017-10-01 19:50:20

How to wait for the end of a request initiated in another component?

Question for Angular2 experts.
At the moment I'm making the project international (ngx-translate), but there was a problem.
* [image 1] -> AppComponent
When the AppComponent component is initialized, the translateSetup() function is executed, which writes the language code (default or English) to the languageCode variable and then stores this value in localStorage.
In the constructor, I subscribe to the user, and if he comes, then I set the languageCode variable of his choice to the language and overwrite the value in localStorage.
59d11c46154f5804352677.png
* [image 2] -> FooterComponent
When initializing the FooterComponent (which is a child of AppComponent) I take the languageCode value from localStorage and then use it (for example, just print to the console).
However, I expect that if the AppComponent still gets in-fa about the user and the data in localStorage is overwritten, then FooterComponent will wait for this process to finish.
59d11c531f414562033105.png
* [image 3] -> ConsoleLog
According to the output in the console, it turns out that AppComponent was initialized first, then FooterComponent was initialized, and then information about the user came. And yes, localStorage has been overwritten, but FooterComponent will no longer receive these changes, since it was initialized earlier.
59d11c60914d9678136180.png
How to make it so that the FooterComponent starts working only after the code in the constructor of the AppComponent component (the place where the subscription is executed) is executed?
Or maybe you can suggest a better way.
PS: Thanks in advance!

Answer the question

In order to leave comments, you need to log in

3 answer(s)
D
denismaster, 2017-10-02
@denismaster

Several offhand options.
1) If the FooterComponent is located next to the AppComponent, use EventEmitter=)
2) If the footer is inside the AppComponent, then just make the Input property inside the Footer, then just make the binding.
3) Create an Observable based on the "storage" event that fires when localStorage changes. More details here and here . But keep in mind that the event occurs on other tabs.

R
Roman, 2017-10-09
@uaKorona

A good solution might be to use an Observable - more specifically a BehaviorSubject.
It unlike Observable always returns the last saved value.
You initialize the application, take the code from the localStorage and put it in a BehaviorSubject.
All other components subscribe to it and receive the latest value.
If at some point, the value changes (I don't know, the user has chosen a different language) - you again put it in the BehaviorSubject and all components (listeners) subscribed to it will be notified of the change

// Behavior Subject

// инициализируем где-то в сервисе и помещаем первое значение 
bSubject = new BehaviorSubject("a"); 

// создаем метод который будет возвращать наш инстанс bSubject 
getSubject = () => return this.bSubject

// В компененте инжектим сервис, вызываем метод getSubject и подписываемся
bSubject.subscribe((value) => {
  console.log("Subscription got", value); 
// Тут выполняем действия при смене языка 
});

// Позже в другом месте пользователь меняет язык и мы сохраняем его опять в поток 
bSubject.next("c"); // Subscription got c

V
Vasily Mazhekin, 2017-10-26
@mazhekin

The correct solution is to move the language acquisition code into the Resolver of the root route, which will be the parent for all other routes in the project. https://angular.io/api/router/Resolve
Then in any case, the storage (or api to the server) will be read before any init of any component. For there is no point in showing any page if we do not know the language yet.
And there you can write to the BehaviorSubject. Which can be read in any component without being afraid that it is empty

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question