170

I have a Component and a Service:

Component:

export class WebUserProfileViewComponent {
    persons: Person [];
    personId: number;
    constructor( params: RouteParams, private personService: PersonService) {
          
        
           this.personId = params.get('id');
           this.persons =  this. personService.getPersons();
           console.log(this.personId);  
        }
}

Service:

@Injectable()
export class PersonService {
      getPersons(){
        var persons: Person[] = [
            {id: 1, firstName:'Hans', lastName:'Mustermann', email: 'mustermann@test.com', company:'Test', country:'DE'},
            {id: 2, firstName:'Muster', lastName:'Mustermann', email: 'mustermann@test.com', company:'test', country:'DE'},
            {id:3, firstName:'Thomas', lastName:'Mustermann', email: 'mustermannt@tesrt.com', company:'test', country:'DE'}
        ];
          
        return persons;
      }
}

I want to get the Person item with the ID ('personID'). The personID I get from Routeparams. For that I need the foreach loop? But I haven't found a solution for this.

Jasperan
  • 2,154
  • 1
  • 16
  • 40
trap
  • 2,550
  • 7
  • 21
  • 42
  • 13
    You can find an element by Id like this persons.find(person => person.id === personId) –  Jun 22 '16 at 13:50
  • 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) – Igor Sep 26 '19 at 15:47
  • Try always to get the data inside the ngOninit method lifecycle hook and not the constructor and try even static data to use observable with – Rebai Ahmed Jul 14 '21 at 00:14

6 Answers6

318

You need to use method Array.filter:

this.persons =  this.personService.getPersons().filter(x => x.id == this.personId)[0];

or Array.find

this.persons =  this.personService.getPersons().find(x => x.id == this.personId);
logisima
  • 7,340
  • 1
  • 18
  • 31
Andrei Zhytkevich
  • 8,039
  • 2
  • 31
  • 45
97

Assume I have below array:

Skins[
    {Id: 1, Name: "oily skin"}, 
    {Id: 2, Name: "dry skin"}
];

If we want to get item with Id = 1 and Name = "oily skin", We'll try as below:

var skinName = skins.find(x=>x.Id == "1").Name;

The result will return the skinName is "Oily skin".

enter image description here

Roby
  • 145
  • 1
  • 12
Hai Dinh
  • 1,499
  • 2
  • 17
  • 30
  • 4
    Thank you for this code snippet, which might provide some limited short-term help. A proper explanation [would greatly improve](//meta.stackexchange.com/q/114762) its long-term value by showing *why* this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Toby Speight Mar 08 '18 at 11:44
  • 1
    How would you do this for an array initially empty then dynamically populated... there seems to be an issue while compiling.... the property e.g Id becomes unknown. – rey_coder Jul 15 '18 at 16:28
  • Hello @rey_coder, I think we should take a check if array not null before we implement to get array's element items. Like: testArray = []; testArrayItem = testArray.length>0? testArray.find(x=>x.Id== 1).Name: 'testArray null'; console.log(testArrayItem); – Hai Dinh Jul 17 '18 at 01:51
  • 1
    Hi @hai-dinh, That sorted the issue. Thanks. – rey_coder Jul 17 '18 at 10:41
12

You could combine .find with arrow functions and destructuring. Take this example from MDN.

const inventory = [
  {name: 'apples', quantity: 2},
  {name: 'bananas', quantity: 0},
  {name: 'cherries', quantity: 5}
];

const result = inventory.find( ({ name }) => name === 'cherries' );

console.log(result) // { name: 'cherries', quantity: 5 }
Nathan Beck
  • 1,152
  • 14
  • 23
10

Transform the data structure to a map if you frequently use this search

mapPersons: Map<number, Person>;

// prepare the map - call once or when person array change
populateMap() : void {
    this.mapPersons = new Map();
    for (let o of this.personService.getPersons()) this.mapPersons.set(o.id, o);
}
getPerson(id: number) : Person {
    return this.mapPersons.get(id);
}
rharari
  • 191
  • 2
  • 5
6

from TypeScript you can use native JS array filter() method:

let filteredElements=array.filter(element => element.field == filterValue);

it returns an array with only matching elements from the original array (0, 1 or more)

Reference: https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Luca C.
  • 11,714
  • 1
  • 86
  • 77
5

Use this code in your service:

return this.getReports(accessToken)
        .then(reports => reports.filter(report => report.id === id)[0]);
Timtech
  • 1,224
  • 2
  • 19
  • 30