'textarea does not update after typing in it

I'm having an issue where the textarea does not update as expected. Here is a screenshot of my webapp:

enter image description here

When I click on any of the buttons "EN", "ZH", "JP", or "HI" then the Query URL box will update with the predefined url as expected. The issue happens when I type anything inside the textarea, then the buttons stop working. This only happens when I type with keyboard and does not happen when I only click on the textarea.

Here is my code, any help would be appreciated:

<label class="ng-label">Examples:</label>
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
    <div (click)="onClickPreDefine(0)" class="btn-group mr-2" role="group" aria-label="Second group">
        <button type="button" class="btn btn-outline-secondary">EN</button>
    </div>
    <div (click)="onClickPreDefine(1)" class="btn-group mr-2" role="group" aria-label="Second group">
        <button type="button" class="btn btn-outline-secondary">ZH</button>
    </div>
    <div (click)="onClickPreDefine(2)" class="btn-group mr-2" role="group" aria-label="Second group">
        <button type="button" class="btn btn-outline-secondary">JP</button>
    </div>
    <div (click)="onClickPreDefine(3)" class="btn-group mr-2" role="group" aria-label="Second group">
        <button type="button" class="btn btn-outline-secondary">HI</button>
    </div>
</div>

<br>

<label class="ng-label">Query URL:</label>
<textarea (keyup)="onKeyQuery($event)" class="form-control" fullWidth rows="5" placeholder="The Url from which you want to fetch the semantic document.">{{query}}</textarea>
import { Component, Input, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
import { ChangeDetectorRef } from '@angular/core';

import { Observable, of } from "rxjs";

// declare var $ : any

@Component({
  selector: 'ngbd-accordion-basic',
  templateUrl: './accordion-basic.html'
})
export class NgbdAccordionBasic {
}


@Component({
  selector: 'app-models-sd',
  templateUrl: './sd.component.html',
  styleUrls: ['./sd.component.scss'],
})

export class SDComponent implements OnInit {
  msgs;

  // clickMessage = '';
  // text1 = '';
  query = '';
  res = '';

  treeview: any[];
  words: any[];
  sentences: any[];
  lists: any[];
  tables: any[];

  predefine_list = ["https://en.wikipedia.org/wiki/Microsoft", "https://zh.wikipedia.org/wiki/%E5%BE%AE%E8%BD%AF", "https://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%BD%E3%83%95%E3%83%88", "https://hi.wikipedia.org/wiki/%E0%A4%AE%E0%A4%BE%E0%A4%87%E0%A4%95%E0%A5%8D%E0%A4%B0%E0%A5%8B%E0%A4%B8%E0%A5%89%E0%A4%AB%E0%A4%BC%E0%A5%8D%E0%A4%9F"];

  overview = require('raw-loader!./markdown/overview.md').default;
  format = require('raw-loader!./markdown/format.md').default;
  annotations = require('raw-loader!./markdown/annotations.md').default;
  example = require('raw-loader!./markdown/example.md').default;
  metrics = require('raw-loader!./markdown/metrics.md').default;
  // get_access = require('raw-loader!./markdown/get_access.md').default;
  sample_code = require('raw-loader!./markdown/sample_code.md').default;
  production_scenario = require('raw-loader!./markdown/production_scenario.md').default;

  constructor(private http: HttpClient, private ref: ChangeDetectorRef) {
    // this.msgs = [{"name": "Root",
    //               "children": [
    //                 {"name": "plaintext", "text":"wowtext"},
    //                 {"name": "haha", "children": [{"name": "plaintext", "text": "hahatext"}]}
    //               ]}]
    this.msgs = [{
      name: "Root", key: 0, children: [
        { name: "DocumentTitle", key: 1, children: [{ name: "plaintext", key: 4, contents: [], text: "Dog Breeds - Types Of Dogs - American Kennel Club\n", "path": "", "children": [] }] },
        { name: "Main", key: 2, children: [{ name: "plaintext", key: 5, text: "maintext" }] },
        { name: "plaintext", key: 3, text: "wwwwtext" }
      ]
    }]
    this.words = [];
    this.sentences = [];
    this.treeview = [];
    this.lists = [];
    this.tables = [];
  }

  ngOnInit() { }

  onKeyQuery(event: KeyboardEvent) { // with type info
    this.query = (event.target as HTMLInputElement).value;
  }

  onClickPreDefine(id) {
    var that = this;
    that.query = that.predefine_list[id];
    // that.ref.detectChanges();
  }

  onClickMe() {
    // this.clickMessage = this.text1;
    if (this.query == "") {
        alert("Query URL cannot be empty!!!");
    }
    else {
    var json_data = {"url": this.query};
    var data2 = JSON.stringify(json_data);
    let options = {
      headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
    };

    var that = this;
    this.http
      .post('/sd_api', data2, options)
      .subscribe(response => {
        that.res = JSON.parse(response['result']);

        that.treeview = [that.res['Annotations']];
        that.sentences[0] = that.res['WordsSentences']['Sentences'];
        that.words[0] = that.res['WordsSentences']['Words'];
        that.lists[0] = that.res["Lists"];
        that.tables[0] = that.res["Tables"];

        if (that.treeview[0] == null)
        {
            alert("Query URL is not yet supported. Please input something else.");
        }

        that.ref.detectChanges();
      });

  }

      that.ref.detectChanges();
  }
}


@Component({
  selector: 'app-models-sd-treeview',
  styleUrls: ['./sd.component.scss'],
  template: `
  <ngb-accordion #acc="ngbAccordion" activeIds="ngb-panel-0" *ngFor="let node of messages">

    <ngb-panel *ngIf="node.name != 'plaintext'" [title]="'>> ' + node.name + ' <<'">


      <ng-template ngbPanelContent>

        <div *ngIf="node.children">
          <div *ngFor="let blockDict of node.children">
            <br *ngIf="blockDict.name == 'plaintext'">
              <app-models-sd-treeview [messages]="[blockDict]" *ngIf="[blockDict]"></app-models-sd-treeview>
              <span style="margin-left: 25px; display: block" *ngIf="blockDict.name == 'plaintext'">{{blockDict.text}}</span>
          </div>
        </div>

        <code *ngIf="node.path"><small>{{ node.path }}</small></code>
      </ng-template>

    </ngb-panel>


  </ngb-accordion>
  `
})
export class TreeViewComponent implements OnInit {
  @Input() messages;
  // displayedRows$: Observable<any>;  // don't use it if you don't know about it

  constructor() { };

  ngOnInit() { }
}


Solution 1:[1]

Instead of using the textarea in a native way, try using ngModel of angular.

<textarea [(ngModel)]='query' class="form-control" fullWidth rows="5" placeholder="The Url from which you want to fetch the semantic document." />

With this you don't even need your onKeyQuery event. Since you're anyway using that to just set the value into query varibale ngModel will help as needed.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pavan Aditya M S