I have a MatStepper
that’s used to navigate to the next page of a signup flow. I also have a method that loads values from a cache if it’s available, and if so then the MatStepper
skips to Page 2. After that, a future method pre-fills the form will those cached values.
The scenario where cachedSports
are retrieved causes the MatStepper
to work and skip to Page 2, but when I try to pre-fill with cachedPets
or cachedAnimals
the MatStepper
fails and gives me the following error:
Cannot read properties of undefined (reading 'next')
There aren’t a lot of differences between cachedSports
and the two failing scenarios, so I don’t know what the culprit is. All three are arrays of strings and the values from their caches are coming in successfully.
// Cached values are retrieved from another file, memory-cache.service.ts loadFromCache(): void { const cachedPets: string[] = this.cacheService.get<string[]>(MemoryCacheService.WellKnownKeys.pets) ?? []; const cachedSports: string[] = this.cacheService.get<string[]>(MemoryCacheService.WellKnownKeys.sports) ?? []; const cachedAnimalNames: string[] = this.cacheService.get<string[]>(MemoryCacheService.WellKnownKeys.animals) ?? []; // Note that cachedPets and cachedAnimalNames share ('targetEveryAnimal') if (cachedPets.length > 0) { this.targetingFormGroup.get('targetEveryAnimal').setValue('Specific'); this.targetPetChange({ value: 'Specific' }, cachedPets); } else if (cachedSports.length > 0) { this.targetingFormGroup.get('targetEverySport').setValue('Specific'); this.targetSportChange({ value: 'Specific' }, cachedSports); } else if (cachedAnimalNames.length > 0) { this.targetingFormGroup.get('targetEveryAnimal').setValue('Specific'); this.targetAnimalChange({ value: 'Specific' }, cachedAnimalNames); } // The values correctly come through: console.log('cachedPets: ', cachedPets); // ["Cat"] console.log('cachedSports: ', cachedSports); // ["Tennis"] console.log('cachedAnimalNames: ', cachedAnimalNames); // ["Chinchilla"] this.goForward(); this.location.replaceState('filters/setup/create/page2'); this.skipPageOne = true; this.cacheService.remove(MemoryCacheService.WellKnownKeys.pets); this.cacheService.remove(MemoryCacheService.WellKnownKeys.sports); this.cacheService.remove(MemoryCacheService.WellKnownKeys.animals); } goForward(){ this.myStepper.next(); // Defined as: @ViewChild('stepper') private myStepper: MatStepper; }
This is where the cached values are actually added into the form
// Same file as the above code validateFormTargeting() { const sports = (spt === 'Specific') ? this.targetingFormGroup.get('sports').value : []; console.log('tfg-sports: ', this.targetingFormGroup.get('sports').value) // ["Tennis"] console.log('sports: ', sports) // ["Tennis"] let pets; let animalNames; if (animt === 'Specific') { // pets = this.tarFormGroup.get // etc animalNames = this.targetingFormGroup.get('animalNames') ? this.targetingFormGroup.get('animalNames').value : []; // The console messages (therefore this code block) is not reached because of the "Cannot read properties of undefined" error console.log('tfg-animalNames: ', this.targetingFormGroup.get('animalNames').value) console.log('animalNames: ', animalNames) } }
Verbose err message:
TypeError: Cannot read properties of undefined (reading 'next') at AppModalFormCreateComponent.goForward (myForm.component.ts:371:20) at AppModalFormCreateComponent.loadFromCache (myForm.component.ts:357:10) at AppModalFormCreateComponent.ngOnInit (myForm.component.ts:227:10)
Advertisement
Answer
It’s the ViewChild
not being defined/set when goForward
is called.
If the template is being updated then it’s probably a timing issue. For testing purposes you can wrap the code in goForward
in a setTimeout()