I have a function called getPuzzle() that calls an API to get data. I want to use that data to modify a div. The issue is that this is all done in the constructor and so the html hasn't been loaded yet.
So I put the code that modifys the html into ionViewDidEnter, however then it runs before the call to the API and it's missing the data this.puzzle
How do I not run this code until the HTML has loaded completely and AFTER the API call?
ngOnInit() {
this.getPuzzle();
}
getPuzzle() {
//Get puzzle info
this.puzzlesService.getPuzzle().subscribe((data) => {
this.puzzleType = this.puzzlesService.puzzleType;
this.puzzle = this.puzzlesService.puzzle;
});
}
ionViewDidEnter() {
//Set first tab
if (this.puzzleType == 'text') {
new Vara("#text", "assets/fonts/vara/Satisfy/SatisfySL.json", [{
text: this.puzzle,
delay: 2000,
x: 2
}], {
fontSize: 25,
strokeWidth: 1.5,
duration: 15000,
color: "black"
});
}
}
CodePudding user response:
Quick Solution
This is pretty deep into the well of trying to use RxJS
imperatively instead of decoratively (Which is a pretty major code-smell with RxJS). Even so, this is one way to ensure that this.puzzlesService.getPuzzle()
inside getPuzzle
has emitted before the code after //Set first tab
is run.
letsGooooooo = new ReplaySubject();
ngOnInit() {
this.getPuzzle();
}
getPuzzle() {
//Get puzzle info
this.puzzlesService.getPuzzle().subscribe((data) => {
this.puzzleType = this.puzzlesService.puzzleType;
this.puzzle = this.puzzlesService.puzzle;
this.letsGooooooo.next("GOOOOOOO!");
});
}
ionViewDidEnter() {
this.letsGooooooo.pipe(
take(1)
).subscribe(_ => {
//Set first tab
if (this.puzzleType == 'text') {
new Vara(
'#text',
'assets/fonts/vara/Satisfy/SatisfySL.json',
[
{
text: this.puzzle,
delay: 2000,
x: 2,
},
],
{
fontSize: 25,
strokeWidth: 1.5,
duration: 15000,
color: 'black',
}
);
}
});
}
More Involved Solution
Fix your service so that puzzlesService
cashes the current puzzle and puzzle type as an observable rather than properties. Then you don't need to re-implement all those functions locally.
ngOnInit() {
// No local version of puzzlesService needed
}
ionViewDidEnter() {
this.puzzlesService.getPuzzle().subscribe(puzzleData => {
//Set first tab
if (puzzleData.puzzleType == 'text') { // puzzleData.puzzleType instead of this.puzzleType
new Vara(
'#text',
'assets/fonts/vara/Satisfy/SatisfySL.json',
[
{
text: puzzleData.puzzle, // puzzleData.puzzle instead of this.puzzle
delay: 2000,
x: 2,
},
],
{
fontSize: 25,
strokeWidth: 1.5,
duration: 15000,
color: 'black',
}
);
}
});
}
CodePudding user response:
You are facing lifecycle issues. So, the best that you can use is ngAfterViewInit();
ngAfterViewInit() {
this.getPuzzle();
}