Cosmic Blog How to Build a Mobile Product Catalog App Using Angular JS, Ionic and Cosmic JS

How to Build a Mobile Product Catalog App Using Angular JS, Ionic and Cosmic JS

by Ivan Larionov on May 18, 2017

TL;DR

View the codebase and follow installation instructions on GitHub.

In this tutorial I’m going to show you how to create a simple catalog mobile app with Cosmic JS and Ionic Framework.

Prerequisites

You’ll need the node.js, npm and ionic cli pre-installed. Make sure you already have them before start. Please refer to ionic docs how to do this. You need Ionic framework >= 2.0 to run this example, so make sure you have the right Ionic version:

ionic -v

Getting Started

First of all we’ll need to create the ionic project. We’ll use standard tabs template and will modify one tab to keep our Catalog component. So once you’ll have all prerequisites installed, you’ll need to setup the new Ionic project:

ionic start cosmic-demo tabs --v2

After you’ll setup this project you’ll be able to run

ionic serve

And play with your app in browser

Setting up Cosmic JS library

First of all, install Cosmic JS Angular/JavaScript library

npm install cosmicjs --save

Now you should be able to import Cosmic object and perform Cosmic JS API calls like following:

import Cosmic from 'cosmicjs';
const bucket = { slug: 'your-bucket-slug' };

Cosmic.getObjects({ bucket }, (err, res) => {
  console.log(res.objects);
});

Setting up things with Cosmic JS

Create the bucket and remember the bucket name (‘cosmic-ionic’ in our case): 

Than create a new object type named ‘Category’ and please remember the object type slug (‘categories’).

We don’t need any additional settings right now, so just set the name and save object type. After save you’ll be redirected to ‘New Category’ page. Create some categories using this page and save them.

Now create the Product object type using the same method as for categories. But we’ll have one difference - please enter the “Metafields Template” tab and add “Image/File” type metafield with key 'image'. This metafield will store the product image.

The second metafield you’ll need to add is “Single Object Relationship”. Please create such metafield and choose Category as “Object type to choose from”.

Such Product structure allows us to create one-to-many relationship between products and categories.

Once Product object type will be created, please add some demo products and assign them to different categories. Make sure you’ll have more than 5 products in single category - this allow us to test infinite scroll.

Ionic part of the app

Create src/pages/categories_list/categories_list.ts file with the following content:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import Cosmic from 'cosmicjs';
import { ProductsList } from '../products_list/products_list';

@Component({
    selector: 'page-categories',
    templateUrl: 'categories_list.html'
})
export class CategoriesList {
    public categories;

    constructor(
        public navCtrl: NavController
    ) {
        this.categories = [];

        Cosmic.getObjectType({
            bucket: {
                slug: 'cosmic-ionc'
            }
        }, {
            type_slug: 'categories'
        }, (err, res) => {
            this.categories = res.objects.all;
        });
    }
    navToCategory(category) {
        this.navCtrl.push(ProductsList, { title: category.title, id: category._id });
    }
}

Than create a template for CategoriesList component:

<ion-header>
  <ion-navbar>
    <ion-title>
      Categories
    </ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
    <ion-list>
        <button ion-item *ngFor="let category of categories" (click)="showProducts()">
            {{ category.title }}
        </button>
    </ion-list>
</ion-content>

Add CategoriesList component to app.module.ts as it’s done with other components like HomePage and set it as first tab for TabsPage component.

What happens here?

Our Categories list component uses Cosmic JS API on its constructor to receive a list of categories we have. It uses two things to achieve the required functionality:

  • Filters objects by Cosmic JS bucket
  • Filters objects by object type

CategoriesList components references ProductsList component - it navigates to products list page once user click on the category item. So we need the ProductsList - component which will show us products list for each particular category. Let’s introduce it!

import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import {Http} from '@angular/http';
import { DomSanitizer } from '@angular/platform-browser'
@Component({
    selector: 'page-products-list',
    templateUrl: 'products_list.html'
})
export class ProductsList {
    public products;
    public category_title;
    constructor(
        public navCtrl: NavController,
        public params: NavParams,
        public http: Http,
        private sanitizer: DomSanitizer
    ) {
        this.products = [];
        this.category_title = this.params.get('title');        this.http.get(`https://api.cosmicjs.com/v1/cosmic-ionc/object-type/products/search?metafield_key=category&metafield_value=${this.params.get('id')}`).subscribe((resp) => {
            let data = resp.json();
            if (data.objects) {
                this.products = data.objects;
            }
            else {
                this.products = [];
            }
        });
    }
    getImageUrl(product) {
        let url = product.metafields.find((v) => { return (v.key == 'image') }).value;
        return `https://cosmicjs.imgix.net/${url}`;
    }
    sanContent(product): any {
        return this.sanitizer.bypassSecurityTrustHtml(product.content);
    }

}

And here we have the ProductsList template:

<ion-header>
  <ion-navbar>
    <ion-title>
      {{ category_title }}
    </ion-title>
  </ion-navbar>
</ion-header>
<ion-content padding>
    <ion-card ion-item *ngFor="let product of products">
        <img [src]="getImageUrl(product)" alt="">
        <ion-card-content>
            <ion-card-title>{{ product.title }}</ion-card-title>
            <div class="white-space-normal" [innerHTML]="sanContent(product)"></div>
        </ion-card-content>
    </ion-card>
</ion-content>

What’s happening here?

Cosmic JS JavaScript library doesn’t provide any method to filter objects by their properties, but REST API does. That’s why we’re doing a HTTP request to Cosmic JS API using Angular Http module.

In this case request URL should look like the following:

https://api.cosmicjs.com/v1/BUCKET_NAME/object-type/OBJECT_TYPE_SLUG/search?metafield_key=CATEGORY_OBJECT_TYPE_SLUG&metafield_value=CATEGORY_OBJECT_ID

The second interesting thing we have to look at is getImageUrl function. Image is a part of product metadata, that’s why it’ll be an item of metafields array for each API response object. Our goal is to extract the required metafieldsarray item (with key field equals to ‘image’ - the key we’ve entering during metafield creation). This array item will also have value key - it’s the image file name, we’ll need to prepend it with https://cosmicjs.imgix.net/ to get full image URL.

We’re using Angular 4 here, that’s why we have to use DomSanitizer to display HTML markup received from Cosmic JS API.

Conclusion

Cosmic JS allows us to quickly start mobile application development without thinking too much about backend and API. Generally, everything can be done using your Ionic/Angular developers and would save you a lof of time and money. Any backend/API entities can be quickly added/removed or modified to meet your project requirements.

You may also like


We're excited to announce some big updates to our branding and website design. We have now changed our name to Cosmic. By dropping the JS from our name, we intend to not only be the best CMS for JavaScript developers, but also for developers using any programming language.

In this installment of the Cosmic JS Developer Spotlight Series, we sat down with Rick Hanlon, a Front End Engineer  and recent New Yorker that is now residing in London, England working on the front end team at Facebook. Rick is also on the core team of Jest, a JavaScript testing platform. Follow Rick on Twitter or LinkedIn and enjoy the Q/A.

We’re excited to announce the official release of Gatsby Preview for Cosmic JS that enables you to add powerful content preview functionality to your Cosmic JS Gatsby website.

We released our additional users Add-on a few weeks ago and it has become one of the most popular products. We think customers really like the flexibility it gives their team to upgrade just a portion of their usage plan instead of jumping up to the next plan. With that flexibility in mind, we are happy to offer two more add-ons to help you get the most out of Cosmic while allowing more billing flexibility.

In this installment of the Cosmic JS Developer Spotlight Series, we sat down with Jacob Knaack, a Web Developer and Technical Communicator residing in Seattle, Washington. Jacob is a Front End Developer at restack, a development studio that finely crafts websites and apps. Jacob is also a frequent contributor to the Cosmic Community, having recently built both the Progressive Apollo Blog as well as the Gatsby Documentation Website. Follow Jacob on LinkedIn and GitHub and enjoy the conversation.

Looking to shortlist some headless content management systems? Our comprehensive list will help you narrow down the growing headless CMS landscape.

Ready to Get Started?

No payment info required.
Start Now   Contact Sales