web-dev-qa-db-fra.com

Obtenir un objet spécifique par identifiant à partir d'un tableau d'objets dans AngularJS

J'ai un fichier JSON contenant des données auxquelles je souhaite accéder sur mon site Web AngularJS. Maintenant, ce que je veux, c'est obtenir un seul objet du tableau. Je voudrais donc par exemple Item avec l'identifiant 1.

Les données ressemblent à ceci:

{ "results": [
    {
        "id": 1,
        "name": "Test"
    },
    {
        "id": 2,
        "name": "Beispiel"
    },
    {
        "id": 3,
        "name": "Sample"
    }
] }

Je voudrais charger les données avec la fonctionnalité AngularJS $ http comme ceci:

$http.get("data/SampleData.json");

qui fonctionne. Mais comment puis-je maintenant obtenir un objet de données spécifique (par id) à partir du tableau que j’obtiens de $http.get?

Merci d'avance pour votre aide.

Salue Marc

109
mooonli

La seule façon de faire est de parcourir le tableau. Évidemment, si vous êtes sûr que les résultats sont classés par ID, vous pouvez faire un recherche binaire

4
Antonio E.

Utilisation de la solution ES6

Pour ceux qui lisent encore cette réponse, si vous utilisez ES6, la méthode find a été ajoutée aux tableaux. Donc, en supposant la même collection, la solution serait:

const foo = { "results": [
    {
        "id": 12,
        "name": "Test"
    },
    {
        "id": 2,
        "name": "Beispiel"
    },
    {
        "id": 3,
        "name": "Sample"
    }
] };
foo.results.find(item => item.id === 2)

J'irais totalement pour cette solution maintenant, car elle est moins liée à angular ou à tout autre framework. Javascript pur.

Solution angulaire (ancienne solution)

J'ai cherché à résoudre ce problème en procédant comme suit:

$filter('filter')(foo.results, {id: 1})[0];

Un exemple de cas d'utilisation:

app.controller('FooCtrl', ['$filter', function($filter) {
    var foo = { "results": [
        {
            "id": 12,
            "name": "Test"
        },
        {
            "id": 2,
            "name": "Beispiel"
        },
        {
            "id": 3,
            "name": "Sample"
        }
    ] };

    // We filter the array by id, the result is an array
    // so we select the element 0

    single_object = $filter('filter')(foo.results, function (d) {return d.id === 2;})[0];

    // If you want to see the result, just check the log
    console.log(single_object);
}]);

Plunker: http://plnkr.co/edit/5E7FYqNNqDuqFBlyDqRh?p=preview

239
Willemoes

Pour ceux qui consultent cet ancien post, c'est la manière la plus simple de le faire actuellement. Cela nécessite seulement un AngularJS $filter. C'est comme Willemoes répondre, mais plus court et plus facile à comprendre.

{ 
    "results": [
        {
            "id": 1,
            "name": "Test"
        },
        {
            "id": 2,
            "name": "Beispiel"
        },
        {
            "id": 3,
            "name": "Sample"
        }
    ] 
}

var object_by_id = $filter('filter')(foo.results, {id: 2 })[0];
// Returns { id: 2, name: "Beispiel" }

WARNING

Comme @mpgn le dit, ceci ne fonctionne pas correctement. Cela va attraper plus de résultats. Exemple: lorsque vous effectuez une recherche sur 3, cela attrape également 23

26
Tillman32

personnellement, j'utilise un trait de soulignement pour ce genre de choses ... donc

a = _.find(results,function(rw){ return rw.id == 2 });

alors "a" serait la ligne que vous vouliez de votre tableau où l'id était égal à 2

25
Jason Boerner

Je veux juste ajouter quelque chose à réponse de Willemoes . Le même code écrit directement dans le code HTML ressemblera à ceci:

{{(FooController.results | filter : {id: 1})[0].name }}

En supposant que "résultats" est une variable de votre FooController et que vous souhaitez afficher la propriété "name" de l'élément filtré.

16
Ena

Vous pouvez utiliser ng-repeat et sélectionner des données uniquement si les données correspondent à ce que vous recherchez en utilisant ng-show, par exemple:

 <div ng-repeat="data in res.results" ng-show="data.id==1">
     {{data.name}}
 </div>    
12

Vous pouvez simplement passer en boucle sur votre tableau:

var doc = { /* your json */ };

function getById(arr, id) {
    for (var d = 0, len = arr.length; d < len; d += 1) {
        if (arr[d].id === id) {
            return arr[d];
        }
    }
}

var doc_id_2 = getById(doc.results, 2);

Si vous ne voulez pas écrire ces boucles compliquées, vous pouvez envisager d'utiliser nderscore.js ou Lo-Dash (exemple dans ce dernier):

var doc_id_2 = _.filter(doc.results, {id: 2})[0]
9
kamituel

Si vous voulez que la liste d’articles comme city soit basée sur l’identifiant de l’état, utilisez

var state_Id = 5;
var items = ($filter('filter')(citylist, {stateId: state_Id }));
8
Ali Adravi

Malheureusement (sauf erreur de ma part), je pense que vous devez parcourir l'objet de résultats.

for(var i = 0; i < results.length; i += 1){
    var result = results[i];
    if(result.id === id){
        return result;
    }
}

Au moins de cette façon, il sortira de l'itération dès qu'il trouvera le bon identifiant correspondant.

7
simonlchilds

Pourquoi compliquer la situation? c'est simple, écrivez une fonction comme celle-ci:

function findBySpecField(data, reqField, value, resField) {
    var container = data;
    for (var i = 0; i < container.length; i++) {
        if (container[i][reqField] == value) {
            return(container[i][resField]);
        }
    }
    return '';
}

Cas d'utilisation:

var data=[{
            "id": 502100,
            "name": "Bərdə filialı"
        },
        {
            "id": 502122
            "name": "10 saylı filialı"
        },
        {
            "id": 503176
            "name": "5 sayli filialı"
        }]

console.log('Result is  '+findBySpecField(data,'id','502100','name'));

sortie:

Result is Bərdə filialı
6
Musa
$scope.olkes = [{'id':11, 'name':'---Zəhmət olmasa seçim edin---'},
                {'id':15, 'name':'Türkyə'},
                {'id':45, 'name':'Azərbaycan'},
                {'id':60, 'name':'Rusya'},
                {'id':64, 'name':'Gürcüstan'},
                {'id':65, 'name':'Qazaxıstan'}];

<span>{{(olkes | filter: {id:45})[0].name}}</span>

sortie: Azərbaycan

4
Celal Muhtar

Je sais que je suis trop tard pour répondre, mais il est toujours préférable de se présenter plutôt que de ne pas se présenter du tout :). ES6 façon de l'obtenir:

$http.get("data/SampleData.json").then(response => {
let id = 'xyz';
let item = response.data.results.find(result => result.id === id);
console.log(item); //your desired item
});
2
Hitesh Kumar

Si vous le pouvez, concevez votre structure de données JSON en utilisant les index de tableau en tant qu'ID. Vous pouvez même "normaliser" vos tableaux JSON tant que vous n'avez pas de problème à utiliser les index de tableaux en tant que "clé primaire" et "clé étrangère", un peu comme le SGBDR. En tant que tel, à l'avenir, vous pouvez même faire quelque chose comme ceci:

function getParentById(childID) {
var parentObject = parentArray[childArray[childID].parentID];
return parentObject;
}

C'est la solution "By Design". Pour votre cas, simplement:

var nameToFind = results[idToQuery - 1].name;

Bien sûr, si votre format d'ID est quelque chose comme "XX-0001" dont l'index de tableau est , vous pouvez soit faire une manipulation de chaîne pour mapper l'ID; ou bien rien ne peut être fait à ce sujet, sauf par l'approche itérative.

2
Antonio Ooi

Le moyen simple d'obtenir (un) élément d'un tableau par identifiant:

La méthode find () renvoie la valeur du premier élément du tableau qui satisfait à la fonction de test fournie. Sinon, indéfini est renvoyé.

function isBigEnough(element) {
    return element >= 15;
}

var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130  only one element - first

vous n'avez pas besoin d'utiliser filter () et de capturer le premier élément xx.filter () [0] comme dans les commentaires ci-dessus

Même chose pour les objets en tableau

var foo = {
"results" : [{
    "id" : 1,
    "name" : "Test"
}, {
    "id" : 2,
    "name" : "Beispiel"
}, {
    "id" : 3,
    "name" : "Sample"
}
]};

var secondElement = foo.results.find(function(item){
    return item.id == 2;
});

var json = JSON.stringify(secondElement);
console.log(json);

Bien sûr, si vous avez plusieurs identifiants, utilisez la méthode filter () pour obtenir tous les objets. À votre santé

function isBigEnough(element) {
    return element >= 15;
}

var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130  only one element - first
var foo = {
"results" : [{
    "id" : 1,
    "name" : "Test"
}, {
    "id" : 2,
    "name" : "Beispiel"
}, {
    "id" : 3,
    "name" : "Sample"
}
]};

var secondElement = foo.results.find(function(item){
    return item.id == 2;
});

var json = JSON.stringify(secondElement);
console.log(json);
1
abosancic

Je voudrais parcourir le tableau de résultats en utilisant un filtre angularjs comme ceci:

var foundResultObject = getObjectFromResultsList (résultats, 1);

function getObjectFromResultsList(results, resultIdToRetrieve) {
        return $filter('filter')(results, { id: resultIdToRetrieve }, true)[0];
    }
0
abovetempo
    projectDetailsController.controller('ProjectDetailsCtrl', function ($scope, $routeParams, $http) {
    $http.get('data/projects.json').success(function(data) {

        $scope.projects = data;
        console.log(data);

        for(var i = 0; i < data.length; i++) {
        $scope.project = data[i];
        if($scope.project.name === $routeParams.projectName) {
            console.log('project-details',$scope.project);
        return $scope.project;
        }
        }

    });
});

Je ne sais pas si c'est vraiment bon, mais cela m'a été utile. J'avais besoin d'utiliser $ scope pour que cela fonctionne correctement.

0
Jordy

utilisez $ timeout et lancez une fonction pour chercher dans le tableau "résultats"

app.controller("Search", function ($scope, $timeout) {
        var foo = { "results": [
          {
             "id": 12,
             "name": "Test"
          },
          {
             "id": 2,
             "name": "Beispiel"
          },
          {
             "id": 3,
            "name": "Sample"
          }
        ] };
        $timeout(function () {
            for (var i = 0; i < foo.results.length; i++) {
                if (foo.results[i].id=== 2) {
                    $scope.name = foo.results[i].name;
                }
            }
        }, 10);

    });
0
Moein Fazeli