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?

Perrier
  • 2,753
  • 5
  • 33
  • 53
  • I'm guessing that from values by default have type `any`, perhaps adding `toString()` behind `searchValues['fieldA']`? – Icycool Feb 11 '20 at 08:57
  • your'e dstructuring an array. so use `map(([PageIndex, PageSize, OrderColumns, searchValues]:[number,number,number,any])=>{...})`. see https://stackoverflow.com/questions/31923739/types-when-destructuring-arrays NOTE: Really I like more `searchValues.fieldA` than `searchValues['fieldA']` – Eliseo Feb 11 '20 at 09:06

1 Answers1

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

Pastabolo
  • 234
  • 1
  • 5
  • I have modified `search$` to private `Subject` but still can not reach the values of searchValues either by `searchValues[0], (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? – Perrier Feb 12 '20 at 13:43
  • `search$` is a `Subject` 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 – Pastabolo Feb 12 '20 at 14:13