Interested in building a web application with Kendo UI for Angular? Learn how in this step-by-step GIF guide.
This GIF guide demonstrates the steps necessary to integrate Kendo UI for Angular into a web app. This is going to be a demo store app that we are building and each new GIF guide will walk you through a different Kendo UI Component. This particular guide walks you through the process of using the Button component as well as setting up a store app and adding products to a "cart." Let's dive in!
Getting Started: Setup
We are starting this GIF guide out with an already begun app. If you need a bit of help in creating your first app, we have a Getting Started Guide! It outlines the steps necessary for setting up your machine to use Kendo UI for Angular. It also provides step-by-step instructions on how to build your first app.

I went ahead and did some styling and created a header, so to follow along, you should clone the beginning seed of the project here.
Quick Note on Service Workers
I did start our project using the Service Worker and --style=scss
flag (more on this in a later GIF guide):
ng new KUI-buttons --style=scss --service-worker
The --service-worker flag takes care of configuring your app to use service workers by adding the service-worker package along with setting up the necessary files to support service workers. For information on the details, see the following section which covers the process in detail as it shows you how to add a service worker manually to an existing app. — Angular.io Guide
Set View Encapsulation to None for Root Component
I also went ahead and set view encapsulation to none on our root component. This is going to allow us to import a styles variable file and all the children components of the root app.component will inherit these styles. Yay cascading styles! From app.component.ts:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
title = 'app';
}
Create the Variable Stylesheet
If you check out the app.component.sass, you will see that I created and imported a variable stylesheet. This is a place for us to store global style variables, like the ones already there. From app.component.sass:
$kendo-orange: #ff6358
$kendo-white: #f8f8f8
$kendo-light-grey: #ededed
$kendo-black: #4b4e52
Now that you have cloned the starter seed to this GIF guide, cd to that project in your terminal and npm install
all the things. Then, let's run the project using ng serve
. You should see this at http://localhost:4200/ in your browser:
Install the Kendo UI Default Theme
Now we are going to install the Kendo UI default theme:
And then we will include the theme in our styles.scss file!
@import '~@progress/kendo-theme-default/scss/all'
Generate the Shirt and Sticker Components
Now before we start using some Kendo UI components, let's go ahead and get our navigation working. We'll start by generating the two components we're missing; T-shirts
and Stickers
.
ng g c t-shirts
ng g c stickers
Create the Navigation Routes
Import the Angular Router Service into app.module.ts
import { RouterModule, Routes } from '@angular/router';
Create Routes
const appRoutes: Routes = [];
Configure Routes
Next, we need to configure our appRoutes
with routerModule.forRoot()
. This goes inside our app.module.ts imports array:
RouterModule.forRoot(
appRoutes
)
Establish Route Paths
Now to create a couple of routes! Our stickers
path needs to point to our StickersComponent
:
const appRoutes: Routes = [
{ path: 'stickers', component: StickersComponent },
{ path: '', redirectTo: '/stickers', pathMatch: 'full' }
];
The empty path in the second route represents the default path for the application, the place to go when the path in the URL is empty, as it typically is at the start.
Create Route for Shirts Component
Remember to leave the most generic routes for last. Order does matter! In this case, we are leaving the empty route until the very end, for our "catch all" route:
Add Navigation in app.component.html
At the top, we'll add a routerLink
attribute with the route for each <a>
element:
<nav>
<a routerLink="/t-shirts">T-Shirts</a>
<a routerLink="/stickers">Stickers</a>
</nav>
Include the router-outlet at the bottom of our app.component.html:
<router-outlet></router-outlet>
Our routes are working now!
Get Active Links to LOOK Active
However, we don't have active styles applying to the links when each route in turn is selected. I've already added .active
styles to the app.component.sass file:
a, a:focus, a:active
color: $kendo-black
text-decoration: none
margin: 14px
&:first-child
margin-left: 0
a.active
font-weight: bold
cursor: default
color: $kendo-orange
We just need to set a routerLinkActive
attribute to the active <a>
element:
<a routerLink="/t-shirts" routerLinkActive="active">T-Shirts</a>
<a routerLink="/stickers" routerLinkActive="active">Stickers</a>
This is going to add a class of .active
to each <a>
element when the routerLink
route is selected.
Watch the magic happen:
Install the Button Component and Dependencies
Let's install the Button
component so we can use it in our app. It's contained in the package, @progress/kendo-angular-buttons
. It has a peer dependency for the Localization
package, @progress/kendo-angular-l10n
, which enables you to translate the components into different languages:
npm install --save @progress/kendo-angular-buttons @progress/kendo-angular-l10n
Import Button and Animation Component into app.module.ts
Animations are a dependency of our Button
component. So, we'll need to include both!
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { ButtonsModule } from "@progress/kendo-angular-buttons";
Be sure to add them to the imports
array as well:
@NgModule({
declarations: [
AppComponent,
TShirtsComponent,
StickersComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
ButtonsModule,
...
],
I went ahead and populated the stickers template for us:
Include Kendo UI Buttons in Stickers Component
Now, let's add our buttons into the stickers componet. So each sticker for sale will have a button to add that sticker to the cart!
<section>
<div class="product">
<div class="product image">
<img src="assets/images/stickers/angular_sticker.jpeg" />
</div>
<button kendoButton (click)="onButtonClick()" [primary]="true">Angular Sticker $5</button>
</div>
<div class="product">
<div class="product image">
<img src="assets/images/stickers/angularjs_sticker.jpeg" />
</div>
<button kendoButton (click)="onButtonClick()" [primary]="true">AngularJS Sticker $5</button>
</div>
<div class="product">
<div class="product image">
<img src="assets/images/stickers/nativescript_sticker.jpeg" />
</div>
<button kendoButton (click)="onButtonClick()" [primary]="true">NativeScript Sticker $5</button>
</div>
<div class="product">
<div class="product image">
<img src="assets/images/stickers/react_sticker.jpeg" />
</div>
<button kendoButton (click)="onButtonClick()" [primary]="true">React Sticker $5</button>
</div>
<div class="product">
<div class="product image">
<img src="assets/images/stickers/vuejs_sticker.jpeg" />
</div>
<button kendoButton (click)="onButtonClick()" [primary]="true">VueJS Sticker $5</button>
</div>
</section>
Add Button Functionality
We need each of these buttons to add their product to the cart. The rest of our game plan will look something like this:
- Generate Cart service
- Import and Include Cart Service inside app.module.ts Provider Array
- Create Product Class
- Create CartItem Class
Generate Cart Service
We are going to need a cart service to give us access to our cart to add/remove items. To generate our cart service, I used the CLI command:
ng g s cart
Import and Include Cart Service inside app.module.ts provider array
import { CartService } from './cart.service';
...
providers: [
CartService
]
Create Classes for product and cartItem
In order to add thing to our cart, we need to create a couple of classes, cartItem
s that will consist of product
s.
Create Product Class
We would like our products to consist of an ID, type, name, and price (in cents) in ./product.ts:
export class Product {
id: number;
type: string;
name: string;
price: number;
}
Create Cart Item Class
We want all of our cart items to have not only the product info (from above) but also the quantity and the size if applicable in ./cartItem.ts:
import { Product } from './product';
export class CartItem {
product: Product;
quantity: number;
size?: string | null;
}
Populate Cart Service
Now, inside our cart service, we will import the cartItem and product classes in cart.service.ts:
import { Injectable } from '@angular/core';
import { CartItem } from './cartItem';
import { Product } from './product';
@Injectable()
Then, we'll create a hard coded productList
for now, with all the stickers:
export class CartService {
// hard coded data, FOR NOW! MUHAHA
productList: Product[] = [
{
id: 0,
type: 'sticker',
name: 'Angular Sticker',
price: 500
},
{
id: 1,
type: 'sticker',
name: 'AngularJS Sticker',
price: 500
},
{
id: 2,
type: 'sticker',
name: 'NativeScript Sticker',
price: 500
},
{
id: 3,
type: 'sticker',
name: 'React Sticker',
price: 500
},
{
id: 4,
type: 'sticker',
name: 'VueJS Sticker',
price: 500
}
];
Next, we need to create a cart that is an array of cartItem
objects:
cart: CartItem[] = [];
constructor() {}
Now for the fun part! We need three functions, one to return the products in the cart (getCart()
), one to return all the available products (getProducts()
) and one to add items into our cart for shopping fun (addToCart
)! Here, we could import and use Observable
and of
from RxJS, but for now I chose to keep it simple:
// Could use Observables if we wanted
// getCart(): Observable<CartItem[]> {
// return of(this.cart);
// }
//
// getProducts(): Observable<Product[]> {
// return of(this.productList);
// }
getCart(): CartItem[] {
return this.cart;
}
getProducts(): Product[] {
return this.productList;
}
Our addToCart()
method needs to be a bit more complex, so let's break it down. We could do something like this:
addToCart(productId): void {
let item = this.productList.find( (product)=>{
return product.id == productId;
});
let cartItem: CartItem = {
product: item,
quantity: 1
};
this.cart.push(cartItem);
console.log('CART:', this.cart);
}
In this implementation, we take the productId
passed in and set item
to the product with a matching id. Then, we take that item and put it into a cartItem
with a default quantity of 1
. Then simply push the cartItem
into the cart. This works of course, but isn't super flexible. If the shopper chooses to buy two of the same sticker, this way would push that same sticker into the cart twice instead of simply updating the quantity of the first sticker. What we'd rather have happen is first check if that product exists in the cart, if it does update the quantity, else push the new product into the cart.
addToCart(productId): void {
let item = this.productList.find( (product)=>{
return product.id == productId;
});
let cartItem: CartItem = {
product: item,
quantity: 1
};
for (let thingInCart of this.cart) {
if (thingInCart.product.id == item.id) {
thingInCart.quantity++;
console.log('CART:', this.cart);
return;
}
};
this.cart.push(cartItem);
console.log('CART:', this.cart);
}
Now that all this cool cart functionality has been created, we can go into our stickers component and use it! For a quick test, let's connect each of the buttons (again, hard coded, I know) and call an addToCart()
method that we need to create in the stickers component. We'll pass in a product ID for each product.
<button kendoButton (click)="addToCart(0)" [primary]="true">Angular Sticker $5</button>
So each of our buttons will have this nifty call on click (click)="addToCart(0)"
.
Finish addToCart Functionality in Stickers Component
Let's create the addToCart
functionality inside our stickers.component.ts by importing the CartService
in stickers.component.ts:
import { Component, OnInit } from '@angular/core';
import { CartService } from '../cart.service';
@Component({
selector: 'app-stickers',
templateUrl: './stickers.component.html',
styleUrls: ['./stickers.component.sass']
})
Then, we'll go ahead and inject our cartService
in the constructor params. We need to do it here, because there are methods on the cartService
which we'd like to use:
export class StickersComponent implements OnInit {
constructor(private cartService: CartService) {}
ngOnInit() {}
}
Create addToCart Function
This function will pass the productId
to the Service and let it handle all the logic:
export class StickersComponent implements OnInit {
constructor(private cartService: CartService) {}
addToCart(productId): void {
this.cartService.addToCart(productId);
}
ngOnInit() {}
}
Cart is Populated
Now when we click the stickers buttons, each sticker is added to the cart!
And if we selected the same sticker multiple times, we see that it just updates the quantity for that product in the cart!
We have much more to do in the way of cleaning up, but for now we will leave that for the next GIF guide! We hope you have enjoyed this first one and look forward to publishing more that will build on where we left off. Happy coding!