Jack Franklin
Jack Franklin

Reputation: 105

Angular 8, trouble passing value through form (click)

New to angular & ts, I greatly appreciate any and all help and apologize for an amateur question.

I am having trouble storing the value from the auto-complete form to a variable and keep getting undefined. I cannot figure out the solution. I want to be able to store the selected option in a variable to be called on in other functions later on.

This is my component HTML

<mat-grid-list cols="1" rowHeight="50px">
<mat-grid-tile>
    <h2>Search job postings:</h2>
    <form>

        <mat-form-field>
            <input type="text" matInput [matAutocomplete]="auto" [formControl]="myControl" />
        </mat-form-field>
        <button (click)="onclick(option)" mat-raised-button color="primary">Search</button>

        <mat-autocomplete role="input" #auto="matAutocomplete"
            [displayWith]="displayFunc">
            <mat-option *ngFor="let option of filterOptions | async" [value]="option">
                {{option}}
            </mat-option>

        </mat-autocomplete>

    </form>
</mat-grid-tile>

And this below is my component.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import { FormControl } from "@angular/forms";
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Component({
  selector: 'app-jobs',
  templateUrl: './jobs.component.html',
  styleUrls: ['./jobs.component.scss']
})
export class JobsComponent implements OnInit {

  public jobs;
  public options: string[] = [];
  public myControl = new FormControl();
  public filterOptions: Observable<string[]>;
  public chosenJob = "";

  constructor(private http: HttpClient) { }
  ngOnInit() {
    let res = this.http.get("myroutehere");
    res.subscribe(data => {
      this.saveData(data);
    });
    this.filterOptions = this.myControl.valueChanges.pipe(
      startWith(''),
      map(value => (this._filter(value))
      ))
  };

  private _filter(value: string): string[] {
    const filterVal = value.toLowerCase();
    return this.options.filter(option =>
      option.toLowerCase().includes(filterVal)
    );
  };

  saveData(resp) {
    this.jobs = resp.jobs
    console.log(this.jobs)
    this.saveJobTitles(this.jobs)
  };

  saveJobTitles(x) {
    x.map(name => this.options.push(name.data.title))
    console.log(this.options)
  };

  // Fills form out with a string instead of object
  displayFunc(subj) {
    return subj ? subj : undefined;
  };


  onclick(value) {
    this.chosenJob = value
    console.log(this.chosenJob);
    console.log(value)
  };

};



Upvotes: 0

Views: 1984

Answers (1)

David G.
David G.

Reputation: 1485

You code looks fine to me, I reproduced it into stackblitz and it seems to work. The only problem I see is you are passing option as an argument in the submit button on click event. That option is only going to be the click event, but it has nothing to do with the input field. You are not going to get the value of the field through there. You are assigning the input to the FormControl object you are creating though, so you can access it through this.myControl.value, that should contain the value of the field. You never mention whether the option list is working fine or not, but I don't see any problems with it.

Here is the stackblitz for reference: https://stackblitz.com/edit/material-select

You are also doing a lot of data manipulation with what you receive from your request, and calling several functions. I think it could be simplified using RxJS,this is untested code though:

ngOnInit() {
  let res = this.http.get("myroutehere")
    .pipe(
       map(resp => resp.jobs),
    )
    .subscribe(names => this.options = names.map(name => name.data.title));
  ...
};

You could get rid of saveData and saveJobTitles that way.

Upvotes: 1

Related Questions