0

I know Angular 2 is old, but I used the best course our library had, and most of it still works...

I have a list of data in a json file, which looks something like this:

    {
        "name"          :"example one",
        "source"        :"",
        "source_type"   :"",
        "text"          :"A bumblebee in the field"
    },
    {
        "name"          :"example two",
        "source"        :"",
        "source_type"   :"",
        "text"          :"Two flowers with red petals"
    },

I can display the whole list of names and can access the other data too. Now I want to have a text field so the user can search. I'd like a search option for name and one for text (even though the text doesn't display directly). The problem is: I'd like users to be able to search for single words, like 'one' and get all results that contain the word 'one'.

Is this possible? Or would I be better of learning how to set up a database online and implement a search option from there?

K Kiek
  • 45
  • 1
  • 8
  • 1
    Possible duplicate of [Find object by id in an array of JavaScript objects](https://stackoverflow.com/questions/7364150/find-object-by-id-in-an-array-of-javascript-objects) – Edric Oct 08 '18 at 11:13

2 Answers2

0

This might give you the idea for the search using filter

var searchText = "three";
    var data = [
      {
        name: "example one three",
        source: "",
        source_type: "",
        text: "A bumblebee in the field"
      },
      {
        name: "example two",
        source: "",
        source_type: "",
        text: "Two flowers with red petals"
      },
      {
        name: "example three",
        source: "",
        source_type: "",
        text: "Two flowers with red petals"
      }
    ];

    let newObj = data.filter((value)=>{
      return value.name.indexOf(searchText) != -1 ? value : null
    });
    console.log(newObj);
Ali Shahbaz
  • 825
  • 1
  • 7
  • 19
  • I get the output I want in the console, but when I manually check the content of newObj, it says that it's undefined (even with a breakpoint at the 'return' statement). I also can't get any of the filtered data on screen. Any suggestions? – K Kiek Oct 08 '18 at 16:49
  • Couldn't edit anymore... It is working now, but still gives me an error that newObj is undefined in the console. I now defined it above, removed 'let' and added 'this.' in front of newObj. – K Kiek Oct 08 '18 at 17:05
  • Where your defined `newObj` and where you accessing the `newObj`? Is it `AJAX` call to get JSON first? – Ali Shahbaz Oct 08 '18 at 17:25
  • I defined it at the top of `export class AppComponent` as `newObj:Obj[];` and then access it in a function `searchObject(text:string) { this.newObj = this.originals.filter((original)` – K Kiek Oct 08 '18 at 17:48
0

Well, you could do this using a Pipe. But using Filter Pipes is not really recommended by the Angular Team. So you can essentially listen to the keyup event on your input field and then call a function to filter the data.

Now, since this is a strict filter object by a key, you can simply use the filter method on Array and check if the indexOf the searchInput in the name or text is >-1

Here's how:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  filterText;

  data = [{
    "name": "example one",
    "source": "",
    "source_type": "",
    "text": "A bumblebee in the field"
  },
  {
    "name": "example two",
    "source": "",
    "source_type": "",
    "text": "Two flowers with red petals"
  }];

  filteredData = [];

  ngOnInit() {
    this.filteredData = [...this.data];
  }

  onChange() {
    console.log('ran');
    this.filteredData = this.data.filter(
      datum => (datum.name.indexOf(this.filterText) > -1 || datum.text.indexOf(this.filterText) > -1));

    console.log(this.filteredData);

  }


}

And in the template:

<input type="text" [(ngModel)]="filterText" (keyup)="onChange()">

<ul>
  <li *ngFor="let datum of filteredData">
    {{ datum.name }}
  </li>
</ul>

Here's a Sample StackBlitz for your ref.

SiddAjmera
  • 38,129
  • 5
  • 72
  • 110