I am declaring a variable with type “FormControl” as below:
@Input() formControlItem: FormControl;
and when setting the value to it in a method as
this.formController.setValue()
it is throwing error “Cannot read property ‘setValue’ of undefined”… while it was working properly in ionic 3.
Can some one plz help?
@lucasbasquerotto
I see that your input is named formControlItem
and you are calling this.formController
.
Assuming that’s just a mistake in copying and pasting, even so you are not passing enough information.
If your component has a selector like my-component
, make sure the input property is being passed correctly, like:
<my-component ... [formControlItem]="myFormControl">
(and make sure myFormControl
is a FormControl
and is defined/initialized)
You can put a log before calling setValue()
to see if it is defined (if it’s in a ngOnChange()
and the component receive several properties, for example, it may be undefined at first, if I’m not mistaken).
console.log('formControlItem', this.formControlItem);
You could log it in ngOnInit()
too.
Sorry for the incomplete information. I thought this much info will be enough.
Actually, I am using “rich-text” component in ionic to implement Rich Text Editor. The git url of the component is https://github.com/judgewest2000/Ionic3RichText. I am getting the error rich-text.ts file, you can refer rich-text.ts file here https://github.com/judgewest2000/Ionic3RichText/blob/master/src/components/rich-text/rich-text.ts.
And also pasting that file code below:
import { StatusBar } from '@ionic-native/status-bar';
import { Component, ViewChild, ElementRef, Input, AfterContentInit, OnInit } from '@angular/core';
import { FormControl } from "@angular/forms";
@Component({
selector: 'rich-text',
templateUrl: 'rich-text.html',
styleUrls: ['rich-text.scss']
})
export class RichTextComponent implements AfterContentInit {
constructor() {
}
@ViewChild('editor') editor: ElementRef;
@ViewChild('decorate') decorate: ElementRef;
@ViewChild('styler') styler: ElementRef;
@Input() formControlItem: FormControl;
@Input() placeholderText: string;
uniqueId = `editor${Math.floor(Math.random() * 1000000)}`;
private stringTools = {
isNullOrWhiteSpace: (value: string) => {
if (value == null || value == undefined) {
return true;
}
value = value.replace(/[\n\r]/g, '');
value = value.split(' ').join('');
return value.length === 0;
}
};
getPlaceholderText() {
if (this.placeholderText !== undefined) {
return this.placeholderText
}
return '';
}
private updateItem() {
const element = this.editor.nativeElement as HTMLDivElement;
if (this.formControlItem != undefined)
element.innerHTML = this.formControlItem.value;
// if (element.innerHTML === null || element.innerHTML === '') {
// element.innerHTML = '<div></div>';
// }
const reactToChangeEvent = () => {
if (this.stringTools.isNullOrWhiteSpace(element.innerText)) {
element.innerHTML = '<div></div>';
if (this.formControlItem != undefined)
this.formControlItem.setValue(null);
} else {
this.formControlItem.setValue(element.innerHTML);
}
};
element.onchange = () => reactToChangeEvent();
element.onkeyup = () => reactToChangeEvent();
element.onpaste = () => reactToChangeEvent();
element.oninput = () => reactToChangeEvent();
}
private wireupButtons() {
let buttons = (this.decorate.nativeElement as HTMLDivElement).getElementsByTagName('button');
for (let i = 0; i < buttons.length; i++) {
let button = buttons[i];
let command = button.getAttribute('data-command');
if (command.includes('|')) {
let parameter = command.split('|')[1];
command = command.split('|')[0];
button.addEventListener('click', () => {
document.execCommand(command, false, parameter);
});
} else {
button.addEventListener('click', () => {
document.execCommand(command);
});
}
}
}
// tslint:disable-next-line:use-life-cycle-interface
ngAfterContentInit() {
this.updateItem();
this.wireupButtons();
}
}
When I interact with the rich-text component, different events (onchange, onkeyup, onpaste, oninput) are called. It is working fine in ionic 3 but in ionic 4, this.formControlItem is not getting initialize and throwing error (as it is undefined). When execution reach to this.formControlItem.setValue(null / element.innerHTML), it throws “cannot read property ‘setValue’ of undefined”.
How are you using the richtext in your HTML (Template)?
Are you passing formControlItem
as an input property?
Something like:
my.component.html:
<rich-text [formControlItem]="myFormControlItem"></rich-text>
my.component.ts:
someFunction() {
this.myFormControlItem = //create the form control
console.log('myFormControlItem ', this.myFormControlItem)
}
Seeing your code, RichTextComponent
expects an input property, so make sure you are passing it properly.
create.html:
<rich-text [formControlItem]="item"></rich-text>
<ion-button expand="full" (click)="clkSubmitListing(item.value)">SAVE</ion-button>
create.ts:
export class create {
item: FormControl;
ionViewWillLoad() {
this.item = this.formBuilder.control('');
}
clkSubmitListing (richText) {
}
}
@lucasbasquerotto
image 1A (ionic 3):
image 1B (ionic 3):
In above, both screenshots are when running ionic 3 code. In which, 1A show rich-text.ts debugger on “this.formControllerItem.setValue()” and value of this.formControllerItem at this time can be shown in image 1B.
image 2A (ionic 4):
image 2B (ionic 4):
In above, both screenshots are when running ionic 4 code. In which, 2A show rich-text.ts debugger on “this.formControllerItem.setValue()” and value of this.formControllerItem at this time can be shown in image 2B.
Put a console.log()
in ionViewWillLoad
, this event is the one that initializes item
, and probably isn’t called, because it seems ionViewWillLoad
was removed:
In this case, the ionViewWillEnter
, ionViewDidEnter
, ionViewWillLeave
, and ionViewDidLeave
have been ported over from V3. Use these events to coordinate actions with Ionic’s own animations system.
Older events like ionViewDidLoad
, ionViewCanLeave
, and ionViewCanEnter
have been removed, and the proper Angular alternatives should be used.
(Although it’s not saying explicitly, I think ionViewWillLoad
was one of those that were removed)
You can change the code to:
ngOnInit() {
this.item = this.formBuilder.control('');
}
1 Like
Yes, it’s working. You always help me. Thousand times thanks my bro.