Partage
  • Partager sur Facebook
  • Partager sur Twitter

(AngularJS) Filter dans ng-repeat

Error: [filter:notarray]

    30 septembre 2016 à 21:28:18

    Bonsoir.

    J'ai à disposition une liste d'objets (posts) stockés dans un array dans un fichier Json :

    [
    	{
    		"id": 1,
    		"title": "Sass",
    		"author": "Lucien Le Roux",
    		"description": "A short tutorial to get you started with Sass! Discover CSS in a new way.",
    		"content": "/articles/tutorials/sass.html"
    	}, {
    		"id": 2,
    		"title": "Blue Yeti",
    		"author": "Clément Da-Purificaçao",
    		"description": "Review of the Blue Yeti microphone.",
    		"content": "/articles/reviews/blue_yeti.html"
    	}, {
    		"id": 3,
    		"title": "Intro to command line",
    		"author": "Lucien Le Roux",
    		"description": "A simple introduction to Linux command-line for newbies.",
    		"content": "/articles/tutorials/command_line.html"
    	}
    ]

    Voici la factory qui s'occupe de chercher ce tableau (j'avoue n'avoir pas encore bien compris le fonctionnement des promesses) :

    app.factory('postFactory', function($http, $q) {
    	var factory = {
    		posts: false,
    		getPosts: function() {
    			var deferred = $q.defer(); // Init nouvelle tache exécutée dans le futur
    
    			if (factory.posts != false)
    				deferred.resolve(factory.posts);
    			else {
    				$http.get('posts.json')
    					.success(function(data, status) {
    						factory.posts = data;
    						deferred.resolve(factory.posts);
    					}).error(function(data, status) {
    						deferred.reject("Impossible de récupérer les articles");
    					});
    			}
    			return deferred.promise;
    		},
    		getPost: function(id) {
    			var deferred = $q.defer(); // Init nouvelle tache exécutée dans le futur
    			var post = {};
    			var posts = factory.getPosts().then(function(posts) {
    				post = factory.posts[id-1];
    				deferred.resolve(post);
    			}, function(msg) {
    				deferred.reject(msg)
    			})
    			return deferred.promise;
    		}
    	};
    	return factory;
    });

    ..Ainsi que le controller qui l'utilise pour récupérer l'ensemble des posts :

    app.controller('postsCtrl', function($rootScope, $scope, postFactory) {
    	$rootScope.loading = true;
    	$scope.posts = postFactory.getPosts().then(function(posts) {
    		$rootScope.loading = false;
    		$scope.posts = posts;
    		console.log($scope.posts);
    	}, function(msg) {
    		alert(msg);
    	});
    });

    Et enfin, voici la vue qui s'occupe de les afficher.

    <div ng-hide="loading">
    	<div>
    		<form>
    			<label>Search by title: </label>
    			<input type="text" ng-model="search.title">
    		</form>
    	</div>
    
    	<div ng-repeat="post in posts | filter: search">
    		<hr>
    		<h1>{{post.title}}</h1>
    
    		<p>{{post.description}}</p>
    
    		<a href="#/articles/{{post.id}}">Let's go!</a>
    	</div>
    </div>

    Vous l'aurez sûrement compris,  je cherche à filtrer les posts par leur attribut title. Or j'obtiens une erreur fort embêtante dans la console :

    angular.js:13920 Error: [filter:notarray] http://errors.angularjs.org/1.5.8/filter/notarray?p0=%7B%22%24%24state%22%3A%7B%22status%22%3A0%7D%7D

    J'ai fait de nombreuses recherches, et j'ai cru comprendre que cela venait du fait qu'un array d'objets est en fait considéré comme un objet, et que du coup le filter d'Angular ne peut pas opérer dessus. Il paraît qu'on peut du coup créer ses propres filtres si besoin, or dans mon cas ce n'est pas un objet mais bel et bien un array !! A ma connaissance, on ne peut pas caster un "objet" (selon JS) en array, donc je suis bloqué. La seule solution que je vois serait de recoder le filter d'Angular pour qu'il fonctionne sur ce soi-disant objet, mais il doit exister un moyen simple auquel je n'ai tout simplement pas pensé.

    Merci de votre attention et merci d'avance si vous avez des solutions. :)

    PS: Le code fonctionne malgré l'erreur. Mais si elle est là, il doit bien y avoir une raison... et un moyen de la faire disparaître.

    PS2: Si quelqu'un sait comment créer des balises spoiler, je suis preneur, copier le code tel quel prend bcp de place ..




    • Partager sur Facebook
    • Partager sur Twitter

    (AngularJS) Filter dans ng-repeat

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown