Using enumerables with arrays

The Ember.Enumerable methods are very important when dealing with arrays. In these recipes, we'll look at some common use cases.

Getting ready

To understand how to use enumerables, we must first take a look at the standard JavaScript array methods and their equivalents using observable enumerables:

Standard method

Observable equivalent

unshift

unshiftObject

shift

shiftObject

reverse

reverseObjects

push

pushObject

pop

popObject

We'll be using some of these methods in our examples, so keep in mind what the standard and observable equivalents are.

The Ember.Enumerable class has several methods that we can use in our Ember applications. Here is the list of the more common methods and what they do:

Enumerable method

Definition

forEach

This iterates through the enumerable, calling the passed function on each item

firstObject

This returns the first object in a collection

lastObject

This returns the last object in a collection

map()

This maps all the items in the enumeration to another value, similar to map in JavaScript 1.6

mapBy()

Similar to map, this returns the value of the named property on all items on the enumeration

filter

This returns an array with all of the items in the enumeration that the passed function returns true

find

This returns the first item in the array that the method returns true

findby

This returns the first item with a property that matches the passed value

every

This returns true only if the passed function returns true for every item in the enumeration

any

This returns true only if the passed function returns true for any item in the enumeration

Many of these methods are similar to their JavaScript counterparts. If you know how to use the JavaScript method, you should be able to use the Ember equivalent as well.

How to do it...

Ember.Enumerables adds all the nice features of Ember objects to enumerables. We'll take a look at several examples on how to do this. The contents for all these recipes are in the chapter2/example6 folder in the app.js file.

Using forEach with an array

A very common use case for an enumerable is iterating over an array with forEach.

  1. Create an array of students:
    const students = ['Erik', 'Jim', 'Shelly', 'Kate'];
  2. Use the forEach enumerable to iterate over the array:
    students.forEach(function(item, index) {
      console.log(`Student #${index+1}: ${item}`);
    });

    The console output will show each student's name in the array:

    Student #1: Erik
    Student #2: Jim
    Student #3: Shelly
    Student #4: Kate
    

    Tip

    Template literals

    Ember is compatible with the latest in ECMAScript 2015. One neat new feature is called template literals or template strings. Template literals are string literals that can stretch across multiple lines and include interpolated expressions. You can do string interpolation by surrounding variables in your strings, like this ${}. Each variable will be displayed in the string as shown in the preceding forEach example.

Using map with an array

The map method takes an array, maps each item, and returns a new modified array. Let's say that we want to make the student names all in uppercase. We can do this using map.

  1. Create a list of students:
    const students = ['Erik', 'Jim', 'Shelly', 'Kate'];

    The first letter is capitalized; however, we want all the letters in uppercase.

  2. Use map to convert every item to uppercase:
    const upperCaseStudent= students.map(function(item) {
      return item.toUpperCase();
    });

    Every item in the array has been converted to uppercase. The new upperCaseStudent array has all the new values.

  3. Use the forEach enumerable to iterate through every item in the array and display its contents:
    upperCaseStudent.forEach(function(item, index) {
      console.log(`student #${index+1}: ${item}`);
    });

    The output displays each name in the new upperCaseStudent array:

    student #1: ERIK
    student #2: JIM
    student #3: SHELLY
    student #4: KATE
    

Using mapBy with an array

The mapBy enumerable can be used if your array is comprised of objects. From each object, we can extract its named properties and return a new array.

  1. Let's create a teacher and student object:
    const student = Ember.Object.extend({
      name: 'Erik Hanchett'
    });
    
    const teacher = Ember.Object.extend({
      name: 'John P. Smith'
      
    });

    Each object has one property called name:

  2. Next we'll instantiate each object.
    const t= teacher.create();
    const s = student.create();
    const people = [s, t];

    Each object is put into a people array:

  3. We can use mapBy to create a new array.
    console.log(people.mapBy('name'));//['Erik Hanchett', 'John P.   Smith']

    This new array returned has the values from the name property from both objects.

Finding the first and last objects in an array

If necessary, we have an easy way to grab the first and last objects in an array.

  1. We'll begin by creating a student array:
    const students = ['Erik', 'Jim', 'Shelly', 'Kate', 'Jenny', 'Susan'];

    This array has six different students.

  2. Let's grab the last object in the array:
    console.log(students.get('lastObject')); //Susan

    This will display Susan, the last object in the array.

  3. Now let's retrieve the first object in the array:
    console.log(students.get('firstObject')); //Erik

    This will display Erik, the first item in the array.

  4. We can push objects on the array as well:
    students.pushObject('Jeff');
  5. The student Jeff has now been added to the list:
    console.log(students.get('lastObject')); //Jeff

Fun with filters

A very common practice is to take an array and return a filtered list of items.

  1. To begin, create an array of numbers:
    const array = [1,2,5,10,25,23];
  2. Take the array and filter it, returning only those numbers over 10:
    const newArray =array.filter(function(item, index, self) {
      return item > 10;
    })
  3. Use console.log to display the new array:
    console.log(newArray); //[25,23]

    This new array has numbers only greater then 10 in it.

Using filterBy with a collection of objects

With filterBy, you can take a collection of objects and filter it by some property.

  1. Create a new student object that has a name and grade:
    const student = Ember.Object.extend({
      grade: null,
      name: null
    });
  2. Add the students to a new array:
    const listOfStudents = [
      student.create({grade: 'senior', name: 'Jen Smith'}),
      student.create({grade: 'sophmore', name: 'Ben Shine'}),
      student.create({grade: 'senior', name: 'Ann Cyrus'})
    ];
  3. Use filterBy to show the students who are seniors:
    const newStudent = listOfStudents.filterBy('grade','senior');

    This returns an array of students who are seniors.

  4. We can double-check the output using forEach:
    newStudent.forEach(function(item,index){
      console.log(item.get('name'));
    });
    Jen Smith
    Ann Cyrus

Using find to get the first match

The find enumerable works very similarly to filter except that it stops after finding the first match.

  1. Create an array of numbers:
    const array = [1,2,5,10,25,23];
  2. Use array.find to retrieve the first number in the list that is over 10:
    const newArray =array.find(function(item, index){
      return item > 10;
    }); 
  3. We'll then check the output of the new array:
    console.log(newArray); //25

    The answer is 25 as it's the first number in the list that is over 10.

Using findBy with collections

The findBy enumerable works very similarly to filterBy except that it stops after finding the first match.

  1. Create a new student object:
    const student = Ember.Object.extend({
      grade: null,
      name: null
    });
  2. Next, create an array of students:
    const listOfStudents = [
      student.create({grade: 'senior', name: 'Jen Smith'}),
      student.create({grade: 'sophmore', name: 'Ben Shine'}),
      student.create({grade: 'senior', name: 'Ann Cyrus'})
    ];
  3. Use findBy to match only the properties that have grade of senior:
    const newStudent = listOfStudents.findBy('grade','senior');
  4. This will return the first student who is a senior:
    console.log(newStudent.get('name')); //Jen Smith

    Jen Smith is the first student who matches this criteria so it is returned to the newStudent array.

Learning with the every enumerable

The every enumerable will return true only if every item matches a certain condition.

  1. Begin by creating an array of numbers:
    const array = [11,25,23,30];
  2. Use the every enumerable to check whether every item in the array is greater than 10:
    console.log(array.every(function(item, index, self) {
      return item > 10;
    })); //returns true

    This returns true because every item in the array is over 10

Using any to find at least one match

The any enumerable will return true if at least one item matches a certain condition.

  1. Once again, create a list of numbers:
    const array = [1,2,5,10,25,23];
  2. Use the any enumerable to check whether any of these numbers in this array are over 10:
    console.log(array.any(function(item, index, self) {
      return item > 10;
    })); //returns true

    This will return true because at least one number is above 10.

How it works...

The Ember.Enumerable mixin is Ember's implementation of the array API defined up to JavaScript 1.8. It's applied automatically on page load so any method is available. In order for Ember to be able to observe changes in an enumerable, you must use Ember.Enumerable.

The enumerable API follows ECMAScript specifications as much as possible so it minimizes incompatibilities with the other libraries. It uses native browser implementations in arrays where available.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset