In the last tutorial, we focused on how to get data into an application using the get
method available on Angular 2’s Http service, and how we can hook into that process to return data in a more friendly format.
In this tutorial, we are going to focus on how to manipulate that data once it is inside of our application using mapping, filtering and reducing. Unlike last time where we were working with observables, this time we will be working directly with normal arrays, and these operations are supported natively by Javascript – it is not specific to RxJS, Angular 2 or Ionic 2.
We are going to go through a specific example in this tutorial, where we will try out….
Before We Get Started
Before you go through this tutorial, you should have at least a basic understanding of Ionic 2 concepts. You must also already have Ionic 2 set up on your machine.
If you’re not familiar with Ionic 2 already, I’d recommend reading my Ionic 2 Beginners Guide first to get up and running and understand the basic concepts. If you want a much more detailed guide for learning Ionic 2, then take a look at Building Mobile Apps with Ionic 2.
An Introduction to Mapping, Filtering, and Reducing Arrays
Before going through some examples, I want to cover the basic theory of how mapping, filtering, and reducing works in Javascript. The general goal of these operations is to take an array, and apply a function to each value in that array in order to do something – what that something is depends on the operation. A map can be used to change the values in an array in some way, filter can be used to remove values from an array, and reduce can be used to calculate some value based on all the values in an array.
All three of these operations work the same way – you call the method on the array you want to manipulate and supply a function to perform the task you want.
We will be using the ES6 syntax, which will allow us to use fat arrow functions, but keep in mind that these operations will also work with standard ES5 syntax, you will just need to change the arrow functions:
(item) => {
// do stuff...
};
to standard functions:
function(item){
// do stuff...
}
Mapping
As I mentioned, mapping allows you to modify the values in an array. We can supply the map
a function that will be applied to every element in the array, and we can return the new value that we want to replace the original value with. Take the example from the last tutorial as an example:
[0, 1, 2, 3, 4, 5].map((item) => {
return item + 1;
});
We have an array with values of 0, 1, 2, 3, 4, 5
and our goal is to modify that array so that each element is incremented by 1
. So we call the map
method on the array, and supply it the following function:
(item) => {
return item + 1;
};
The map will apply this function to every single element in the array, and whatever element is currently being processed will be passed into the function as item
. We can then do whatever we want to this item
and whatever we return
will be used as the new value. In this case, we just increment the value by 1, and then return it, which will result in the following array:
[1, 2, 3, 4, 5, 6];
You could also just as easily double the number, triple it, divide it, or simply make every value in the array become cats
:
(item) => {
return 'cats';
};
which would result in:
['cats', 'cats', 'cats', 'cats', 'cats', 'cats'];
Filtering
Filtering is very similar in concept to mapping, but instead of creating a function that changes values, we create one that determines whether or not it should be included in the array. If the function returns true
then the value will be included in the array, if it returns false
then it will be excluded from the array. Let’s create a new example:
[0, 1, 2, 3, 4, 5].filter((item) => {
return true;
});
Like the map, filter will apply this function to every value in the array. All our function does is return true
so the function will pass for every value, and so the array will remain unchanged. This obviously isn’t very useful. Instead, we could supply the filter a function that will test the value passed in as item
against some condition, like this:
[0, 1, 2, 3, 4, 5].filter((item) => {
return item % 2 === 0;
});
Now we’re using the modulo operator to calculate the remainder of the item when it is divided by 2. If the remainder is 0, it means we have an even number. Thus, this filter will only include items in the array that are even. The result will be:
[0, 2, 4];
Another use might be to exclude any words that are over 4 characters from an array:
['cats', 'kittens', 'puppies', 'dogs'].filter((item) => {
return item.length < 5;
});
which will result in:
['cats', 'dogs'];
Reducing
Like map and filter, reduce also applies a function to each value in the array, but it doesn’t necessarily result in a new array. Reduce not only supplies you with the value of the current value being operated on, but also the previous value that was returned. This allows you to either compare values in the array, or combine them in some way.
We could create the following reduce function to figure out the highest number in an array:
[0, 1, 2, 3, 4, 5].reduce((previous, current) => {
return Math.max(previous, current);
});
The above example compares the current and previous value to see which is higher and then passes that value into the next iteration of the function. The result will be the highest number, which is 5
.
We could also figure out the sum of all numbers in the array with the following function:
[0, 1, 2, 3, 4, 5].reduce((previous, current) => {
return current + previous;
});
Now with each iteration of the function, the sum of the previous and current will be passe along, resulting in a sequence like:
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15
So, the result of the reduce function will be 15
in this case. Note that you can also supply an initial value for previous
, rather than using the first value of the array, if you add an additional parameter as shown below:
[0, 1, 2, 3, 4, 5].reduce((previous, current) => {
// do something...
}, 5);
1. Generate a new Ionic 2 Application
Now that we’ve covered the theory, we are going to create an Ionic 2 application that pulls in some data from a JSON file, and then performs some map, filter, and reduce operations on that data in a more realistic scenario.
We are going to create a blank application that only uses a single page.
Run the following command to generate a new Ionic 2 project:
ionic start ionic2-map-filter-reduce blank --v2
We are also going to need to add a JSON file to our project which will store all of our data. To do that, you should follow these steps:
Create a new folder inside of the www folder called data
Create a new file in the data folder called recipe-data.json and add the following to it:
{
"categories": [
{
"title": "Breakfast",
"image": "images/eggs.jpeg",
"recipes": [
{
"title": "Eggs on Toast",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/eggs.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Pancakes",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/pancakes.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Waffles",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/waffles.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Fruit Platter",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/fruit.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
},
{
"title": "Lunch",
"image": "images/nachos.jpeg",
"recipes": [
{
"title": "Sandwich",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/sandwich.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Nachos",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/nachos.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Burgers",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/burger.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Fries",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/fries.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
},
{
"title": "Dinner",
"image": "images/steak.jpeg",
"recipes": [
{
"title": "Burgers",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/burger.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Steak",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/steak.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Pizza",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/pizza.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Chicken Salad",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/main.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
},
{
"title": "Dessert",
"image": "images/cupcake.jpeg",
"recipes": [
{
"title": "Macarons",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/macarons.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Iceblock",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/iceblock.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Custard Pudding",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/custard.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Trifle",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/dessert.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
},
{
"title": "Snacks",
"image": "images/cookie.jpeg",
"recipes": [
{
"title": "Chocolate",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/chocolate.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Coookies",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/cookie.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
},
{
"title": "Healthy",
"image": "images/strawberries.jpeg",
"recipes": [
{
"title": "Stir-fry",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/healthy.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Pancakes",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/pancakeshealthy.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Chicken",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/main.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
},
{
"title": "Cakes",
"image": "images/chocolatecake.jpeg",
"recipes": [
{
"title": "Birthday Cake",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/cake.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Kids Cake",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/sprinklecake.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
},
{
"title": "Drinks",
"image": "images/red.jpeg",
"recipes": [
{
"title": "Iced Tea",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/icetea.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Green Smoothie",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/greensmoothie.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Martini",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/martini.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
}
]
}
Now that we have everything set up that we need, we are going to walk through some examples.
2. Mapping in Ionic 2
We already know that mapping allows us to take an array, and transform the values in that array somehow. We are going to create an example that fetches the recipe data above, and then uses a map function to modify the categories
data in some way.
Add the following code to the
constructor
function in home.ts:
this.http
.get('data/recipe-data.json')
.map((res) => {
return res.json().categories.map((item) => {
item.recipes = item.recipes.length;
return item;
});
})
.subscribe((data) => {
console.log(data);
});
By default, our categories
array contains a recipes
property that allows us to access an array of all the recipes in that category. But let’s say in this case we don’t need all of the recipes data, we just need to know how many recipes there are in the category. So, we use a map function to modify to access each element in the array, and set its recipes
property to be the length of the recipes
array.
Before adding the map, the result would have looked like this:
but afterwards it looks like this:
Notice that we are using map
on the observable returned by get
as we discussed in the last tutorial, but then we are also using a map
directly on the array that is returned by accessing the categories
property after converting the JSON response into a Javascript object.
As I mentioned in the last tutorial, when a map
is used on an observable, it will apply to each item that the observable emits. In the case of fetching data with Http the observable only ever emits one item, and the map
function is applied to that item as a whole. The item returned here is a single Response object, so the map
function is used once to convert that Response object into a Javascript object containing the data we wanted (by calling the .json()
method). All the map does is create that Javascript object for us, it doesn’t then also apply the map function to data within that object.
Since we want to manipulate the data inside that Javascript object, we access the categories
array after the response has been converted, and create a new map
function on that. This is now just a standard Javascript map function, which is different to the first map
function we use which is only for observables and is provided by RxJS.
This is why we have two return
statements, the first return
statement is for the observables map
function, and the second return
function is for the arrays map
function. I realise this may be a little confusing to wrap your head around, but once it clicks you’ll get it.
3. Filtering in Ionic 2
Now we are going to create an example with filter. Unlike a map which changes the values values in an array, filter removes them. We are going to create a filter function that will exclude any elements from the categories
array that do not have more than 2 recipes.
Add the following code to the
constructor
function in home.ts:
this.http
.get('data/recipe-data.json')
.map((res) => {
return res.json().categories.filter((item) => {
return item.recipes.length > 2;
});
})
.subscribe((data) => {
console.log(data);
});
As you can see, the format is very similar to the map. The only difference being that rather than returning the new value that should be used in the array, we return true
or false
value which will determine whether of not that element will be excluded from the array.
4. Reducing in Ionic 2
Reducing is a little different to the previous two examples, so it might be a little harder to figure out. We are going to create an example that will again make use of the categories
array, but this time rather than creating a new array like filter and map do, we want to return a single value, which represents the largest amount of recipes in any category. That is, if the category with the most recipes has 8
recipes, then the reduce function should return 8
.
Add the following code to the
constructor
function in home.ts:
this.http
.get('data/recipe-data.json')
.map((res) => {
return res.json().categories.reduce((pre, cur) => {
let prevResult = Number.isInteger(pre) ? pre : pre.recipes.length;
return Math.max(prevResult, cur.recipes.length);
});
})
.subscribe((data) => {
console.log(data);
});
What is happening here is that we create a function that is passed in two values by reduce: the previous
value (pre) and the current
value (cur).
Like map and filter, the function is applied to each element in the array one by one, and the current
value represents whatever element in the array the function is up to. The difference here is that we also have a previous
value, which represents the value that was returned in the last iteration of the function.
We grab the higher of the two recipe length values, and return that. This means that the higher value gets passed on to the next iteration of the function and is compared to the next value, then the higher of those two is passed on and so on, eventually resulting in a number that represents the highest number of recipes found in a category.
There’s a bit of shenannigans going on here though that we need to talk about:
let prevResult = Number.isInteger(pre) ? pre : pre.recipes.length;
For anybody not familiar, this is a ternary operator which is essentially just a condensed if / else
statement. This could be rewritten as:
let prevResult;
if (Number.isInteger(pre)) {
prevResult = pre;
} else {
prevResult = pre.recipes.length;
}
We are attempting to compare two values with the max
method, which will only accept numbers as parameters. Unlike previous examples, which have worked with arrays of numbers, the categories
array here is actually an array of objects
. We want to grab the length of the recipes
array inside of each of the category objects, which is fine because it returns a number.
So pre.recipes.length
works on the first iteration because it uses the first element in the array as the intial previous value, which in this case would be the following data:
"categories": [
{
"title": "Breakfast",
"image": "images/eggs.jpeg",
"recipes": [
{
"title": "Eggs on Toast",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/eggs.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Pancakes",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/pancakes.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Waffles",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/waffles.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
},
{
"title": "Fruit Platter",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
"image": "images/fruit.jpeg",
"details": "<h2>Ingredients</h2> <ul> <li>Milk</li> <li>Bread</li> <li>Cinnamon</li> <li>Water</li> <li>Lemon</li> <li>Flour</li> <li>Sugar</li> <li>Chocolate</li> <li>Nuts</li> </ul> <h2>Method</h2> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>"
}
]
},
The recipes
array here as 4 elements, so pre.recipes.length
will have a result of 4. This will be compared to the next element in the array which is in the same format, and also has 4 elements. So our Math.max
call will become:
Math.max(4, 4);
and the result of this will be 4, so the reduce
function returns this value and that will be passed into the next iteration of the function. So, the next iteration will have a previous
value of 4
and a current
value of a category object.
On the first iteration, we were dealing with two objects, now we are dealing with one number and one object. We can’t call pre.recipes.length
if pre
is just a number. That’s why we do the following check:
let prevResult = Number.isInteger(pre) ? pre : pre.recipes.length;
If the previous result is a number (meaning it is not the first iteration) we just use the number directly, and if the previous result is not a number (meaning it is the first iteration) we grab the length property of the recipes array.
Once each value in the array has been processed, the reduce
function will return our final value, which in this case will be 4
, which represents the largest amount of recipes in a single category.
Summary
These are truly powerful functions to understand, you can perform small operations that are going to make your code a bit tidier and easier to write, but you can also perform complex operations in a really simple manner. It may take some time to get your head around, especially the reduce
function, but it is certainly something worth learning.