0

I'd like to rewrite some of my forms using FormGroups to enable the easier bulk validation of inputs, etc. My problem is that I have been using RxJs to gather value changes and start to get data from the server according to the new values as these input fields are mostly datatable column filters.

What I have so far:

FormGroup:

private inputGroup = new FormGroup({
        fieldA: new FormControl(),
        fieldB: new FormControl(),
        fieldC1: new FormControl(),
        fieldC2: new FormControl(),
});

Inputs:

<input class="form-control" type="text" name="fieldA" formControlName="fieldA" />
<input class="form-control" type="text" name="fieldB" formControlName="fieldB" />
<input class="form-control" type="text" name="fieldC1" formControlName="fieldC1" />
<input class="form-control" type="text" name="fieldC2" formControlName="fieldC2" />

An Observable:

private search$ = new Subject<string[] | undefined>();

A method that gathers all parameters into the needed Observable:

protected getCombinedParams(): Observable<GetParams> {
    return combineLatest([
        ...this.combineDefaultsBase,
        this.search$,
    ]).pipe(
        map(([PageIndex, PageSize, OrderColumns, searchValues]) => ({
            PageIndex, PageSize, OrderColumns,
            FieldA: searchValues['fieldA'],
            FieldB: searchValues['fieldA'],
            FieldC: [searchValues['fieldC1'], searchValues['fieldC2']]
        } as GetParams)));
}

this.combineDefaultsBase is in a base class and contains basic parameters for sorting, number of rows per page and page number.

I have the inputGroup valuechanges trigger my observable:

 this.inputGroup.valueChanges.pipe(
        debounceTime(defaultInputDebounceTime)
    ).subscribe(newValue => {
        this.search$.next(newValue);
    });

The GetParams class:

export interface GetParams {
  FieldA?: string;
  FieldB?: string;
  FieldC?: string[];
}

What I want to be able to do is to map the values from the FormGroup array got from valuechanges to the desired GetParams values. Ts is complaining right now on the FieldA: searchValues['fieldA'] line saying

(TS) Element implicitly has an 'any' type because expression of type '"fieldA"' can't be used to index type 'number | string[]'. Property 'fieldA' does not exist on type 'number | string[]'.

How said that it's a number? Where is it coming from?

2
  • I'm guessing that from values by default have type any, perhaps adding toString() behind searchValues['fieldA']? Commented Feb 11, 2020 at 8:57
  • your'e dstructuring an array. so use map(([PageIndex, PageSize, OrderColumns, searchValues]:[number,number,number,any])=>{...}). see stackoverflow.com/questions/31923739/… NOTE: Really I like more searchValues.fieldA than searchValues['fieldA'] Commented Feb 11, 2020 at 9:06

1 Answer 1

1

In your case, the type of searchValues is string[] | undefined (because this is the value coming from search$ which is a Subject<string[] | undefined>())

The problem is that you can't access field properties of arrays of undefined.

searchValues['fieldA'] is not defined because of the type of searchValues

Sign up to request clarification or add additional context in comments.

2 Comments

I have modified search$ to private Subject<string[]> but still can not reach the values of searchValues either by searchValues[0], (<string[]>searchValues)[0], searchValues['fieldA'], or searchValues.fieldA. It gives the previous error if I try to address by name and undefined otherwise. The values are in the searchValues however, by name. So eg. searchValue.fieldA contains what is expected. Shall I declare a new class with the properties of searchValues and use that instead of a simple array?
search$ is a Subject<string[]> so searchValues is a string[] = an Array of strings. By doing searchValues.fieldA you're trying to access to property fieldA of your array of strings, it sounds like there is a problem there

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.