how to filter an ngRepeat loop according to the value of one of the contents of an array

Asked

Viewed 1,081 times

4

Well, the content of a page on my site is generated from the following JSON template:

[
  {
    "company":{
      "name":"Nome do Cliente",
      "url":"#"
    },
    "client":{
      "name":"Projeto",
      "url":"#"
    },
    "tags":[
      "tag1",
      "tag2",
      "tag3"
    ],
    "description":"Lorem Ipsum",
    "image":"#"
  }
]

And then it’s displayed as follows:

<div class="row portfolio-item" ng-repeat="project in projects">
    <div class="image hidden-sm hidden-xs col-md-6">
        <img class="layout" src="{{project.image}}">
        <span class="mask"></span>
    </div>
    <section class="col-md-6 col-sm-12 col-xs-12 portfolio-content">
        <header>
            <h2>{{project.company.name}}/{{project.client.name}}</h2>
            <nav class="tags">
                <a ng-repeat="tag in project.tags" href="/tag/{{tag}}">{{tag}}</a>
            </nav>
        </header>
        <article>
            <p>{{project.description}}</p>
        </article>
    </section>
</div>

However, I would like to be able to filter the displayed content according to the selected tag. I tried to use the attribute filter:tag, but the angular returns no result. ('tag' was defended with a scope variable in the controller with one of the values of the JSON tag array)

4 answers

2


Well, based on @Pedro Luz’s response and this answer, I arrived at the following code that solved my problem:

.filter('filterBySelectedTag', function() {
    return function(projects, selectedTag){
        if(selectedTag == null){
            var filtered = projects;
        }else{
            var filtered = [];
            angular.forEach(projects, function(project) {
                angular.forEach(project.tags, function(tag){
                    if( tag == selectedTag )
                        filtered.push(project);
                });
            });
        }
        return filtered;
    }
});
  • 1

    Mark your answer as a solution. It will stay at the top independent of voting.

  • 1

    I can only mark my answer as a solution tomorrow... =/

0

Dude, I would advise you not to rewrite the wheel, because then the maintenance would be horrible. In your specific case, just do the following

<div ng-repeat="tag in tags | filter: { property: valor }"></div>

It is much cleaner and organized without having to declare any filters. In this case, I passed an object to the filter, not just a value

Example: Imagine a div where you wanted to filter the active items, in which case it would be

<div ng-repeat="item in items | filter: { active: true}">
      <span>{{ item.qualquer_coisa }}</span>
</div>
  • I don’t think you understand what I want to do. Following your code I would only filter the tag loop, and my need was to filter the content from the tags. Besides, I ran a test and your code didn’t work. Hug

0

Matthew, I don’t know if it’s exactly what you need... but in one of my projects I own a ng-repeat in a JSON and mount some filters from values typed in <input>. Example below:

<table>
  <thead>
    <tr>
      <th>#</th>
      <th>
        <input type="text" ng-model="search.contactName">
        Nome do contato
      </th>
    </tr>
  </thead>

  <tbody>
    <tr ng-repeat="item in filtered = (list | filter:{contactName: search.contactName })">
      <td>
        <strong>[[ $index + 1 ]]</strong>
      </td>
      <td>[[ item.contactName ]]</td>
    </tr>
  </tbody>
</table>

0

As @Pedro Luz responded, the idea is right, going into the use of Angular filters, but they are used differently.

For example, I want to change the way a date is displayed?

I use the following Angular Binding:

{{ date | (filtro aqui) }}

Exemplifying:

{{ date | dd }}

That would return the day in numerical format (17, as today is December 17).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.