Create an eCommerce app with Ionic, Capacitor, and Commerce.js
Tags: ionic, angular, commercejs, cart
Published: 2021-01-21 02:47:42

---
title: Create an eCommerce app with Ionic, Capacitor, and Commerce.js
published: true
description: 
tags: ionic, angular, commercejs, cart
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/5uxn7nsqy6v7wvufrqa9.png
---

For this tutorial, we'll be creating a single-page mobile app to display and purchase products using the Chec API.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l3qgk0yruxywhsncgz5e.png)

Before we start, create an account at [Chec](https://commercejs.com/). Then add a few categories and products and grab a copy of your public API key (Settings > Developer). 

If you don't feel ready to create an account, you can use the test API key provided in their docs:

`pk_184625ed86f36703d7d233bcf6d519a4f9398f20048ec`

## Stack
Here's the stack that we're going to use for our app:

* Ionic: 5.0.0
* Angular: 10.0.0
* Commerce.js: 2.3.0
* Capacitor: 3.0.0 (Beta)

## Setup

First, open your terminal and execute the following instruction to create a new Ionic project.

```shell
ionic start IonicCommerce blank --type=angular
```

For this guide, we'll use Angular since it's the framework I feel more comfortable with.

If everything went well, we should have our Ionic project based on the `list` template on a new folder called IonicCommerce.

The Ionic CLI will also ask if we want to add [Capacitor](https://capacitorjs.com/). This is optional but if you want to give it a try just make sure to review the required [dependencies](https://capacitorjs.com/docs/getting-started/dependencies) for each platform. 

At the time of writing this post, the new Capacitor 3.0 is still in beta, for that reason the CLI will install the 2.4 version but I'm curious to try the new version so we'll skip the default integration for now.

Now open the project in your code editor. For VSCode users run `code .` in your command line, or open the app as you normally would do.

## Setup Commerce.js

Let's `cd` into our project `cd ./IonicCommerce`, and type `npm i @chec/commerce.js` to install the SDK that later will help us working with the Chec API.

Next, create a service to initialize and expose the Commerce.js instance by running the following command:

```bash
// This will create a file at src/services/commerce-client.service.ts
ionic g service services/commerce-client --skipTests=true
```

Let's import and initialize the commerce.js instance as follows:

```ts
import { Injectable } from '@angular/core';
import Commerce from '@chec/commerce.js';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root'
})
export class CommerceClientService {

  private mClient: any;

  constructor() {
    this.mClient = new Commerce(
      environment.commerceApiKey,
      !environment.production,
    );
  }

  get client(): any {
    return this.mClient;
  }

}
```
This a simple class with three members: a private property called 'mClient', a constructor, and a `getter` that will be used later in the app to easily access the commerce.js client.

When creating the Commerce.js instance we should pass two parameters: the API key that you can grab in your Chec Account and a boolean value to enable/disable the debug mode.

Notice that we're importing the environment.ts file where we have defined the API key.

```ts
// environment.ts
export const environment = {
  production: false,
  commerceApiKey: 'pk_184625ed86f36703d7d233bcf6d519a4f9398f20048ec',
};
```

*Currently Typescript support for the Commerce.js SDK is in [WIP](https://github.com/chec/commerce.js/tree/feature/commerce.ts), so for now, we'll declare our commerce.js client as `any`.*

## Display products

Now that our service is all set, let's create a page to show the product catalog.

```shell
// This will create a new folder under src/pages/products with all the component files.
ionic g page pages/products --spec=false
```

The first thing that we need to do is to inject our `CommerceClientService` into the products page.

```js
import { CommerceClientService } from 'src/app/services/commerce-client.service';

export class ProductsPage implements OnInit {
  constructor(private commerce: CommerceClientService) {}
}
```

Now let's create a function to retrieve the products using our injected `CommerceClient`.

```ts

public products: any = [];

async loadProducts() {
    try {
      const { data: products } = await this.commerce.client.products.list();
      this.products = products
    } catch {
     // a network error occurred or something went wrong
    }
}
```
Since `ngInit` is executed once our component is created, it is the perfect place to invoke our `loadProducts` method.

```ts
ngOnInit() {
   this.loadProducts();
}
```

For our view we're going to use the following structure:

```html
<ion-header>
  <ion-toolbar color="dark">
    <ion-title>Products</ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
  <ion-list>
    <ion-item *ngFor="let product of products">
      <ion-thumbnail style="--border-radius: 10px" slot="end" *ngIf="product.media.source">
        <img [src]="product.media.source" />
      </ion-thumbnail>
      <ion-label>
        <h2>{{ product.name }}</h2>
        <p>{{ product.price.formatted_with_symbol }}</p>
        <ion-button color="dark" (click)="onBuyNowButtonTouched(product)">
          Buy now
        </ion-button>
      </ion-label>
    </ion-item>
  </ion-list>
</ion-content>
```

Notice the `<ion-button>` has a binding to the `click` event, so let's add a method to handle it in our component.

When the button is pressed, we'll take the user to the hosted checkout URL to finish the checkout process.

```ts
onBuyNowButtonTouched(product: any) {
  window.open(product.checkout_url.checkout, '__target');
}
```

Finally, let's build and serve our app by executing `ionic s`. Once the app is up and running, navigate to the `/products` path, and if everything is ok you should see the list with all the product catalog!

## Bonus: Capacitor 3.0 🌝

Now let's see what Capacitor 3.0 can do for us.

Install the Capacitor package as follows:
```bash
npm i @capacitor/core@next @capacitor/cli@next
```

Run the following to set the app name and package id.
```bash
npx cap init
```

Open the `src/main.ts` file and import the Capacitor library.

```ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

// Add this line
import '@capacitor/core';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));
```

Deploy the app to an iOS simulator by executing the following commands:

```bash
npm i @capacitor/ios@next
npx cap add ios
ionic build
npx cap run ios
```

{% youtube q75lEmqVtCc %}

The cool thing with Capacitor 3.0 is that there's no need to open Xcode in order to build and run the app. The `npx cap run ios` will put all the pieces together for us.

## Last few words
This is just a start to work with Commerce.js. There's so much to be done for a more robust commerce experience. 

With that said, I highly recommend checking out [IonShop UI Headless](https://gum.co/ionshop-ui), our premium template that comes with better Commerce.js integration, including customer authentication, cart, variants, and an integrated checkout with payment methods, shipping zones, taxes calculation, and more.