dynamic-component

Learning Dynamic Components — Making a Pizza Creator App using Angular

In the previous post of “You don’t Know Angular” series, we have discussed how we project data into a component. We have learned…

Learning Dynamic Components — Making a Pizza Creator App using Angular

In the previous post of “You don’t Know Angular” series, we have discussed how we project data into a component. We have learned projections at specific places inside the component using the projection slots concept.

In this post, we are going to learn “ How and Why of Dynamic Components”

We will learn:

  • How to create a dynamic component?
  • How to attach @Input to a Dynamic Component?

Let’s understand these concepts using a Pizza Creator Application.

Problem Statement

Suppose, you own a pizza shop, where anybody can order a customized pizza. The customization of the pizza is dependent on the customer and will be displayed at the end. You need to design a software that displays a pizza along with its customization at the end of each order.

Pizza and the toppings 😄

Approach

Now, we understood the problem, as each of the pizza is different, we can not define a set template for the pizza content. We will generate the pizza dynamically to place the order.

Generating Pizza dynamically? 😕 Yes, the customer will select the toppings and we will make the delicious pizza component dynamically based on the selection.

Angular provides us the Dynamic Component Loader which makes this very easy for us to create these components. In Angular, we can use the componentFactoryResolver to resolve the factory which is a requirement to create any component.

Our first task, is to create two components

  • Choices Component — To help the customers, to choose the toppings on the Pizza.
  • Pizza Component — To create the pizza dynamically

Note: The choices component will use the Pizza Component to create a pizza dynamically.

Creating the Choices Component

The choices component will have the following parts:

  • Toppings Array containing all choices
  • SelectTopping Method for choosing the toppings
  • DOM node to Inject the Dynamically Created Component
  • CreatePizza Method to create the Pizza Component dynamically

Let’s begin by creating and initializing the toppings Array. We have placed all our images inside the assets/ and the name of these images are the same as the name of the elements inside the toppings array.

Toppings Array

Now, we will loop this array to display our choices on the page.

Looping Toppings Array

Now, our page contains the toppings panel to click and select any of the toppings for the pizzas which looks like below:

Toppings Panel

Awesome !! Now, it’s time to add selectToppings Method, to select these toppings on click. We will push the selected toppings in an array and will call it selectedToppings array.

The selected topping Method is a toggle method for the topping. It pushes and removes the toppings from the selectedToppings array.

selectedToppings Method to select Toppings

In the template, we need to event bind this method, with each topping in the toppings panel we described above.

Icons for selectToppings

Now, we have maintained the array for selecting and deselecting the topping.

After creating these two functionalities, we need to decide Where are we going to insert our dynamic pizzas? For this, we need to use @ViewChild to access the id from the DOM. It is similar todocument.querySelector() . We have created a DOM element with the id pizza inside the choice.component.html .

<div #pizza></div>

We can now get this pizza element from the DOM using @ViewChild

@ViewChild('pizza', {read: ViewContainerRef}) pizza: ViewContainerRef;

We can now write the CreatePizza Method. This is important to understand that we need a ComponentFactoryResolver from @angular/core. We will initialize it inside the constructor like this:

constructor(private resolver: ComponentFactoryResolver) {}

After this, We will create a PizzaComponent which we are going to inject dynamically inside the #pizza DOM node using ComponentFactoryResolver.

Here are the steps for creating the component:

  • Resolve the Factory of the component you want to create using a resolveComponentFactory method on the resolver.
  • Use the createComponent method to create the component and pass the factory inside it as a parameter.

We will create a simple button to bind the createPizza method by event binding.

<div class="createPizza">
<button (click)= createPizza()>Create Pizza</button>
</div>
After creating the dynamic component always remember to add them to EntryComponents Array inside app.module.ts
From Docs :
if your app happens to bootstrap or dynamically load a component by type imperatively, you must add it to entryComponents explicitly.

We will add like:

@NgModule({
   entryComponents: [PizzaComponent]
})

Now, you should be able to create a Pizza like this:

Pizza Creator

Awesome !! We finally have the pizza base that is created dynamically. We can create multiple pizzas like that.

We also have our selectedToppings array ready, we just need to send it to Pizza Component. H

Hmm 🤔… Can we use @Input here?

@Input and Dynamic Components

The point to note here is that we don’t need to use an @Input decorator for dynamic inputs. We can simply create a variable inside our dynamic Component, here ( Pizza Component ) and can use the instance property to update it from the component which is creating it dynamically here ( Choices Component ).

So, we will create the toppings property inside the PizzaComponent

export class PizzaComponent {
toppings: string[];
}

And then, will update it with our selectedToppings Array inside Choices Component

Choices Component Sending Data to Dynamic Component
Remember, we will empty the selectedToppings array every time before creating a new pizza.

Finally, we need to bind this array to the template of PizzaComponent

Binding Data to Pizza Component

The function getMyStyles here is used for adding the toppings always in circles. It includes the combination of cos and sine functions, to ensure that the toppings always remain inside the pizza. You can ignore it, if you want :)

Adding Styles to Toppings

Today, I realised the importance of Trignometry 😐

Yay…. Our Application is now complete and is ready to serve delicious pizzas, let’s check this:

Complete Pizza App

Live Link : https://aayusharora.github.io/Pizza-Creator-App/

Github: https://github.com/aayusharora/Pizza-Creator/tree/master/myapp

Credits: Todd Motto for SVG’s

Enjoy these delicious pizzas till the next blog post, we will explore more concepts related to components in the coming posts. Till then ng-bye 😄

If you liked the article, please clap your heart out. Tip — Your 50 claps will make my day!

Please also share on Fb and Twitter. If you’d like to get updates, follow me on Twitter and Medium. If anything is not clear or you want to point out something, please comment down below.


© 2019. All rights reserved.

Powered by Hydejack v8.1.0