How can Angular JS ng-repeat select a random grouping from an array?

I have a set of 6 unique objects in an array.

In my ng-repeat list, I want to display 3 different items from the array each time.

On each refresh, the selection may change but it's essential that the 3 items are distinct and don't repeat among themselves.

For example, if the array consists of colors like

[red, yellow, blue, green, purple, cyan, fuchsia]
, then upon refreshing, I might see:

red,blue,green
purple,blue,yellow
fuchsia,green,red

It doesn't matter if a color appears more than once consecutively, as long as there are no duplicates within the same set such as red, blue, blue.

The code snippet I'm using is:

<ul class="ch-grid">
  <li ng-repeat="user in home.testimonials|orderBy:random|limitTo: 3">
    <div class="ch-item ch-img-1" style="background-image: url(assets/images/{{user.image}})">
      <div class="ch-info">
        <h3>{{user.quote}}</h3>
      </div>
    </div>
    <h3 class="name">{{user.name}}</h3>
    <p class="title">{{user.title}}</p>
  </li>
</ul>

And in my controller:

_this.random = function () {
  return 0.5 - Math.random();
};

_this.testimonials = [
  // testimonial objects here
];

However, the current implementation displays more than 3 items at once instead of limiting to only 3.

Attempting a solution with a custom filter recommended by @csschapker:

(function () {
  'use strict';

  angular.module('pb.ds.home').filter('getThree', function () {
    return function (array) {
      var copy = angular.copy(array);
      var sample = [];
      while (sample.length < 3) {
        var randomIndex = Math.floor(Math.random() * (copy.length));
        sample.push(copy[randomIndex]);
      }
      return sample;
    };
  });
})();

Utilizing this filter method in the HTML:

<ul class="ch-grid">
  <li ng-repeat="user in home.testimonials|filter:getThree">
    <div class="ch-item ch-img-1" style="background-image: url(assets/images/{{user.image}})">
      <div class="ch-info">
        <h3>{{user.quote}}</h3>
      </div>
    </div>
    <h3 class="name">{{user.name}}</h3>
    <p class="title">{{user.title}}</p>
  </li>
</ul>

Unfortunately, the filter is not functioning as expected and all 6 items are being displayed. There seems to be an oversight on my end.

Answer №1

Using ng-repeat with random and limitTo filters.

<div ng-repeat="item in itemList|orderBy:random|limitTo:3">{{item}}</div>

Answer №2

This provided solution offers a good start for creating a filter, however, there are some issues that have been pointed out in the comments section. In order to ensure clarity and effectiveness, I have decided to keep this answer along with the comments for reference purposes. Alternatively, I have formulated a new and improved approach to address the problem at hand.

To enhance your filtering process, you can incorporate a custom filter:

.filter('randomFilter', function() {
    return function(customArray, sampleLength) {
        var duplicate = angular.copy(customArray);
        var customizedSample = [];
        while(customizedSample.length < sampleLength) {
            var randomIdx = Math.floor(Math.random() * (duplicate.length));
            customizedSample.push(duplicate.splice(randomIdx, 1)[0]);
        }
        return customizedSample;
    };
})

Implementation is as follows:

<li ng-repeat="item in customArray | randomFilter:3">{{ item }}</li>

An illustrative demonstration is available on Plunker for further examination: http://plnkr.co/edit/NgsQlvgrCD7vLXnBC7q1?p=preview

Answer №3

After numerous trials, it appears that the most effective approach is to retrieve random values in your controller after the array has been populated. Here's an example:

_this.sample = [];
var copy = angular.copy(_this.testimonials);
while(_this.sample.length < 3) {
    var randomIndex = Math.floor(Math.random() * (copy.length));
    _this.sample.push(copy.splice(randomIndex, 1)[0]);
}

Then simply use ng-repeat="user in home.sample"

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to record the text within a span tag

HTML: <div id="myID"> <h3 class="level-title"> <span class="level-title-text"> Awesome Movie </span> </h3> </div> JS: var movieTitle = document.getElementById('myID').getElementsB ...

AngularJS location service error

My goal is to configure the login page on my master controller so that when the username and password are both set to "admin", it will redirect me to the "/tables" path. However, every time I attempt to log in, I encounter the following error: TypeError: ...

The error message "[Insecure URL]" was triggered at line 85 of angular.min.js in the AngularJS framework

Looking for some assistance with Angular as I have limited knowledge. It was working fine on localhost, but after upgrading from PHP5 to PHP7, I encountered this error: angular.min.js:85 Error: [$sce:insecurl] http://errors.angularjs.org/1.2.13/$sce/inse ...

Can UTF8-byte-chunks be decoded to a string in a safe manner?

Is it safe to decode a UTF8-string that has been split into arbitrary byte-chunks into a string (chunk by chunk)? Also, what about an arbitrary encoding? The scenario involves the following method: async getFileAsync(fileName: string, encoding: string):s ...

Iterating through a collection using a foreach loop and performing concatenation operations as

<?php $names =array('Alex','Billy','Tabby'); $names_str=null; foreach($names as $key => $names) { $names_str .= $name; if(key!= (count($names)-1)) { $names_str.=', '; } } echo $names_str ...

Attempt the axios request again if the response is null or missing

await axios .post( executeBatch, { headers: { "Content-Type": "application/json", "x-access-token": localStorage.getItem("token"), }, } ) .then( ...

Deleting list element from a function in bash

How can I delete an element from a list within a function? What's the reason behind push_list working as intended but not pop_list? #!/bin/bash declare -a item_list=() add_item() { item_list[${#item_list[@]}]="`echo $@`" } remov ...

PhpStorm alerts users to potential issues with Object methods within Vue components when TypeScript is being utilized

When building Vue components with TypeScript (using the lang="ts" attribute in the script tag), there is a warning in PhpStorm (version 2021.2.2) that flags any methods from the native JavaScript Object as "Unresolved function or method". For exa ...

Encountering an AngularJS glitch with the manifest.appcache

Scenario 1: After receiving the 'cached' event from window.applicationCache.addEventListener, I switch my mobile to OFFLINE MODE (airplane mode), then I open my webapp from the HomeScreen icon and everything works fine, except for AngularJS, whic ...

How can you find the middle element of a nested array using Ruby?

Looking for a Ruby method to calculate the median that can handle nested arrays? Similar to "uniq" and "sort_by," this method allows you to specify which values within the nested array should be considered. class Array def median . . . end end ...

Angular React Form: Issue locating control within deeply nested FormArray structure

I am currently developing a nested, dynamic form where users can create groups and nest conditions within those groups or add new group objects within a `group` FormArray. The UI prototype is still under development, with some pieces not fully functional y ...

Unlock the power of deep linking with the Branch SDK and integrate seamlessly with

Trying to utilize Branch's deep-linking features, particularly deferred deep-linking, in my Ionic project has been a challenge. The issue lies in the incomplete documentation provided for Cordova/Ionic integration by Branch. Despite installing their C ...

Reset sinon stub post-test

During my testing, I have a stub like this: sinon.stub(service, 'batchNote') .resolves(mResponse); After the test is completed, would it be feasible to remove or clear this stub? If so, what method can be used? ...

What is the maximum length for the string that can be passed to jQuery's .append() method?

In Angular, I developed a simple program that leverages router functionality to showcase two pages within a single-page application. The setup includes a page with two navigational buttons and a wrapper div (ng-view) that dynamically displays the content o ...

Loop through, conditionally display, and perform comparisons on different components of a date object

I am currently working on creating an event listing using Angular and I am facing a challenge. I want to dynamically add a year and month element between event listings based on changes in the year/month. <body ng-controller="CalendarController"> & ...

Interacting with Vue.js: Exploring click events and the concept of "this"

I have a vue project with a to-do list feature, and I'm facing an issue when trying to use pop() to remove items from the list. Below is the relevant code snippet: // components Vue.component('todoitem', { template: "<li>Test Item ...

Transform JSON data into an HTML table using PHP

My goal is to dynamically convert a JSON array into an HTML table using PHP. The challenge lies in the fact that this data can vary with each request, meaning the JSON may contain different arrays and/or different associated names. For example, I have two ...

Struggling to determine whether an array contains data or is void in ReactJS?

In the state, I have an array and I set the default value of my state to an empty array []. After loading an API request, I need to display a loader until the data is ready. So, I am using a condition like this: (if the array length === 0, the loader wil ...

dynamic variable to store user input (Meteor)

I'm still trying to grasp the concept of reactive programming in Meteor, so I have a question that may seem silly: Instead of "injecting" data using the template system as documented, can I use it to extract data? For example, if I have a textarea li ...

Angularjs: a powerful tool for passing data efficiently between controllers

In my angular.js application, I have implemented multiple views and I am in need of maintaining the status across view changes. To achieve this, I have created a simple factory to share data between controllers. Instead of using "$scope" in the controllers ...