<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Manuel Popa</title>
    <description>The latest articles on DEV Community by Manuel Popa (@manuelpopa).</description>
    <link>https://dev.to/manuelpopa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F817703%2Fb49afb9b-c246-4ecd-9409-42f0f0bf92ce.jpeg</url>
      <title>DEV Community: Manuel Popa</title>
      <link>https://dev.to/manuelpopa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manuelpopa"/>
    <language>en</language>
    <item>
      <title>Building an Ionic app using ConfigCat’s Feature Flags</title>
      <dc:creator>Manuel Popa</dc:creator>
      <pubDate>Mon, 01 Aug 2022 17:51:11 +0000</pubDate>
      <link>https://dev.to/manuelpopa/building-an-ionic-app-using-configcats-feature-flags-3mo1</link>
      <guid>https://dev.to/manuelpopa/building-an-ionic-app-using-configcats-feature-flags-3mo1</guid>
      <description>&lt;p&gt;We live in a world overflowing with information, where we’re connected and online almost every single day. Informational overload is a real thing, and we should all be aware enough not to fall victim to this behavioral pattern loop.&lt;/p&gt;

&lt;p&gt;To-do lists are a real hail-mary in today’s clickbaity and attention-grabbing world, so I figured that it’d be fun for us to build our very own to-do app from scratch, using Ionic and &lt;strong&gt;&lt;a href="https://configcat.com/"&gt;ConfigCat's feature flags&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Ionic?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ionicframework.com/"&gt;Ionic&lt;/a&gt;&lt;/strong&gt; is a platform for building neat hybrid (PWA) apps for both Android and iOS, using JavaScript. &lt;br&gt;
Up until Ionic 4, we had a perfect symbiosis between the Ionic and Angular frameworks, where Ionic was mostly responsible for providing the UI components while Angular was used as the foundation for the mobile application.&lt;br&gt;
The arrival and adoption of web components broke this symbiosis and Ionic became framework-agnostic, meaning that you can use it with or without any framework. &lt;br&gt;
The core of the Ionic SDK is the Capacitor, a cross-platform native bridge used to turn any web project into a native iOS or Android mobile application. It includes a rich library of plugins that enable easy access to most native device features with basic JavaScript.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is a feature flag, and why use ConfigCat?
&lt;/h3&gt;

&lt;p&gt;A feature flag is simply a toggle used to activate or deactivate specific features you may have in your application. &lt;br&gt;
Here are some examples of why you may want to use a feature flag: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;giving early access to new features to a select few;&lt;/li&gt;
&lt;li&gt;targeting specific countries;&lt;/li&gt;
&lt;li&gt;various testing purposes. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could create your own in-house feature flag service or choose from an array of services available online such as &lt;strong&gt;&lt;a href="https://configcat.com/"&gt;ConfigCat&lt;/a&gt;&lt;/strong&gt;. &lt;br&gt;
&lt;strong&gt;&lt;a href="https://configcat.com/"&gt;ConfigCat&lt;/a&gt;&lt;/strong&gt; has everything you need from such a service in the free tier, including all the security features. Check it out &lt;strong&gt;&lt;a href="https://configcat.com/#pricing"&gt;here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Starting our to-do list.
&lt;/h3&gt;

&lt;p&gt;The first thing on our to-do list (pun intended) is to generate a new Ionic project using: 'ionic start ionic-to-do blank'. This command will generate a blank template for our project.&lt;br&gt;
The structure is pretty common. We'll have an src folder where our application will store its components and providers (also known as services).&lt;br&gt;
Inside the src folder, we can find the following folders - app, assets, pages, providers, and theme. &lt;br&gt;
The root component is located in the file src/app/app.component.ts. This file is important because it will be the first component added to the application, and it will be used to display all other components on top of it, just like a tree.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';

import { HomePage } from '../pages/home/home';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage:any = HomePage;

  constructor(platform: Platform) {
    platform.ready().then(() =&amp;gt; {});
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we’re importing our HomePage in the root component so we can set it as the rootPage of our application. We can use the 'any' type since TypeScript is strongly typed which makes the declaration of each variable a little more complicated compared to JavaScript. We use 'any' when the type is not known from the beginning, or when you work with variables that may change over time.&lt;br&gt;
Next, we need to set our rootPage in the template found in src/app/app.html:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ion-nav [root]="rootPage"&amp;gt;&amp;lt;/ion-nav&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having set our root page, we need to take care of the navigation for the other pages. This can be done using 'push' and 'pop' to navigate between the needed views on the top of the main page. &lt;br&gt;
The 'push' method is used to display a new view, while 'pop' will remove the current view and go back to the previous one.&lt;/p&gt;

&lt;p&gt;Let's turn our attention to the pages folder, where we add home, item-detail, and add-item folders for each of the respective views. &lt;br&gt;
Each folder will include the template and the class for the view.&lt;/p&gt;

&lt;p&gt;The home.html file combines Ionic elements with Angular directives, as you can see from the snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ion-header&amp;gt;
  &amp;lt;ion-navbar color="secondary"&amp;gt;
    &amp;lt;ion-title&amp;gt;
        My to-do list
    &amp;lt;/ion-title&amp;gt;
    &amp;lt;ion-buttons end&amp;gt;
        &amp;lt;button ion-button icon-only (click)="addItem()"&amp;gt;&amp;lt;ion-icon name="add-circle"&amp;gt;&amp;lt;/ion-icon&amp;gt;&amp;lt;/button&amp;gt;
    &amp;lt;/ion-buttons&amp;gt;
  &amp;lt;/ion-navbar&amp;gt;
&amp;lt;/ion-header&amp;gt;

&amp;lt;ion-content&amp;gt;
  &amp;lt;ion-list&amp;gt;
    &amp;lt;ion-item *ngFor="let item of items" (click)="viewItem(item)"&amp;gt;{{item.title}}&amp;lt;/ion-item&amp;gt;
  &amp;lt;/ion-list&amp;gt;
&amp;lt;/ion-content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file contains some Ionic specific elements like 'ion-header' and 'ion-content' - they are Ionic UI components that can be reused throughout the application. Some of these elements also have specific Ionic attributes. &lt;br&gt;
For example, ‘ion-buttons’ has an ‘end’ attribute  used to automatically place that element at the end of the nav bar (right of the screen). &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gE4_2Bce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0218qmieleknyk0ga5t5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gE4_2Bce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0218qmieleknyk0ga5t5.PNG" alt="App nav bar" width="414" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can attach listeners to these elements by using the parenthesis - in our case, the button element has a click event which will call the method addItem().&lt;br&gt;
On the other hand, *ngFor is an Angular directive used for iterating through an array of objects and creating elements that will be inserted into the DOM. &lt;br&gt;
To control the functionality of the home page, we need the home.ts file which has the class 'HomePage':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { ModalController, NavController } from 'ionic-angular';
import { AddItemPage } from '../add-item/add-item'
import { ItemDetailPage } from '../item-detail/item-detail';
import { Data } from '../../providers/data';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  public items = [];

  constructor(public navCtrl: NavController, public modalCtrl: ModalController, public dataService: Data) {
    this.dataService.getData().then((items) =&amp;gt; {
      if(items){
        this.items = items;
      }
    });
  }

  ionViewDidLoad(){  }

  addItem(){
    let addModal = this.modalCtrl.create(AddItemPage);

    addModal.onDidDismiss((item) =&amp;gt; {
       if(item){
          this.saveItem(item);
       }
    });
    addModal.present();
  }

  saveItem(item){
    this.items.push(item);
    this.dataService.save(this.items);
  }

  viewItem(item){
    this.navCtrl.push(ItemDetailPage, {
      item: item
    });
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this file, we use ionViewDidLoad - an Ionic lifecycle hook to be triggered when the page is loaded. Also, importing the NavController from 'ionic-angular' helps us control the toggle of our views using 'push' and 'pop' (I mentioned them earlier).&lt;br&gt;
There are also three custom methods which we can use for adding, saving, and viewing our items. &lt;br&gt;
The next view will be constructed in the add-item folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ion-header&amp;gt;
  &amp;lt;ion-toolbar color="secondary"&amp;gt;
    &amp;lt;ion-title&amp;gt;
        Add Item
    &amp;lt;/ion-title&amp;gt;
        &amp;lt;ion-buttons end&amp;gt;
            &amp;lt;button ion-button icon-only (click)="close()"&amp;gt;&amp;lt;ion-icon name="close"&amp;gt;&amp;lt;/ion-icon&amp;gt;&amp;lt;/button&amp;gt;
        &amp;lt;/ion-buttons&amp;gt;
    &amp;lt;/ion-toolbar&amp;gt;
&amp;lt;/ion-header&amp;gt;
&amp;lt;ion-content&amp;gt;
  &amp;lt;ion-list&amp;gt;
    &amp;lt;ion-item&amp;gt;
      &amp;lt;ion-label floating&amp;gt;Title&amp;lt;/ion-label&amp;gt;
      &amp;lt;ion-input type="text" [(ngModel)]="title"&amp;gt;&amp;lt;/ion-input&amp;gt;
    &amp;lt;/ion-item&amp;gt;
    &amp;lt;ion-item&amp;gt;
      &amp;lt;ion-label floating&amp;gt;Description&amp;lt;/ion-label&amp;gt;
      &amp;lt;ion-input type="text" [(ngModel)]="description"&amp;gt;&amp;lt;/ion-input&amp;gt;
    &amp;lt;/ion-item&amp;gt;    
  &amp;lt;/ion-list&amp;gt;
    &amp;lt;button full ion-button color="secondary" (click)="saveItem()"&amp;gt;Save&amp;lt;/button&amp;gt; 

&amp;lt;/ion-content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time we encounter a new Angular specific functionality - [(ngModel)] - which is used for two-way data bindings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { NavController, ViewController } from 'ionic-angular';

@Component({
  selector: 'page-add-item',
  templateUrl: 'add-item.html'
})
export class AddItemPage {
  title: string;
  description: string;

  constructor(public nav: NavController, public view: ViewController) { }

  saveItem(){
    let newItem = {
        title: this.title,
        description: this.description
    };

    this.view.dismiss(newItem);
   }

   close(){
    this.view.dismiss();
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The class for add-item has a new Ionic service called ViewController, which is imported just like the NavController from 'ionic-angular'. This service helps close the modal using the 'dismiss' method which can also be used to pass the item saved to the home page through this event.&lt;br&gt;
This new component (AddItemPage) will be imported into the home.ts file so we can use it to create the add item modal.&lt;br&gt;&lt;br&gt;
The next item on our to-do list is the item-detail component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ion-header&amp;gt;
  &amp;lt;ion-navbar color="secondary"&amp;gt;
    &amp;lt;ion-title&amp;gt;
      {{title}}
    &amp;lt;/ion-title&amp;gt;
  &amp;lt;/ion-navbar&amp;gt;
&amp;lt;/ion-header&amp;gt;

&amp;lt;ion-content&amp;gt;
  &amp;lt;ion-card&amp;gt;
    &amp;lt;ion-card-content&amp;gt;
      {{description}}
    &amp;lt;/ion-card-content&amp;gt;
  &amp;lt;/ion-card&amp;gt;
  &amp;lt;ion-card *ngIf="dueDate"&amp;gt;
    &amp;lt;ion-card-content&amp;gt;
      {{dueDate}}
    &amp;lt;/ion-card-content&amp;gt;
  &amp;lt;/ion-card&amp;gt;
&amp;lt;/ion-content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing new on this template. However, we will use a feature flag inside the ItemDetailPage class.&lt;/p&gt;

&lt;h3&gt;
  
  
  ConfigCat will help us toggle our new feature.
&lt;/h3&gt;

&lt;p&gt;Let's say that we want to implement a new application feature and make it available for some beta users. Our new feature will take the form of  another element on our to-do card called 'dueDate':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { NavParams } from 'ionic-angular';

@Component({
  selector: 'page-item-detail',
  templateUrl: 'item-detail.html'
})
export class ItemDetailPage {

  title;
  description;
  dueDate;

  constructor( public navParams: NavParams ) { }

  ionViewDidLoad() {    
    this.title = this.navParams.get( 'item' ).title;
    this.description = this.navParams.get( 'item' ).description;
    this.dueDate = this.navParams.get( 'item' ).dueDate;
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The change for the feature flag will be made in the add-item.ts file. This is the component used to control what details are added to the item card. &lt;/p&gt;

&lt;p&gt;ConfigCat has good &lt;strong&gt;&lt;a href="https://configcat.com/docs/"&gt;documentation&lt;/a&gt;&lt;/strong&gt;. The entire process of setting it up will take about 10 minutes. The first thing to do is to navigate to ConfigCat and &lt;strong&gt;&lt;a href="https://app.configcat.com/login"&gt;sign up&lt;/a&gt;&lt;/strong&gt; for a free account. Then you can create the feature flag:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q4cp476C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zlp5ssmwjjvm1g7t4i55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q4cp476C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zlp5ssmwjjvm1g7t4i55.png" alt="ConfigCat feature flag" width="880" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to install the &lt;strong&gt;&lt;a href="https://configcat.com/docs/sdk-reference/js/"&gt;configcat-js package&lt;/a&gt;&lt;/strong&gt; via npm - 'npm install configcat-js'. This will give access to the ConfigCat client to use our newly created flag in our application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { NavController, ViewController } from 'ionic-angular';
import * as configcat from 'configcat-js';

@Component({
  selector: 'page-add-item',
  templateUrl: 'add-item.html'
})
export class AddItemPage {

  title: string;
  description: string;
  dueDate: string;
  configCatClient;
  flag;

  constructor(public nav: NavController, public view: ViewController) {
    this.configCatClient = configcat.createClient( "1K3ZCCa1S0GKW6RN4S5wyA/o33xY-5E_U-aEzyeTlme_g", {} );
    this.configCatClient.getValueAsync( "isMyFirstFeatureEnabled", false ).then( value =&amp;gt; { 
      this.flag = value;
    });
}

   saveItem(){
      let newItem = {
         title: this.title,
         description: this.description,
         dueDate: this.dueDate
      };

      this.view.dismiss(newItem);
   }

   close(){
      this.view.dismiss();
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how we added the three new properties to our AddItemPage class - dueDate, configCatClient, and flag. &lt;br&gt;
AddItemPage.flag is the property that will keep the value which we retrieve from the &lt;strong&gt;&lt;a href="https://configcat.com/"&gt;ConfigCat&lt;/a&gt;&lt;/strong&gt; client. Based on this value, we’ll show or hide the 'Due Date' item using Angular's *ngIf directive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--igM0HqNA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1ggiiyrxyeqau2rlrdx.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--igM0HqNA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1ggiiyrxyeqau2rlrdx.PNG" alt="App add item" width="410" height="358"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ion-header&amp;gt;
  &amp;lt;ion-toolbar color="secondary"&amp;gt;
    &amp;lt;ion-title&amp;gt;
        Add Item
    &amp;lt;/ion-title&amp;gt;
        &amp;lt;ion-buttons end&amp;gt;
            &amp;lt;button ion-button icon-only (click)="close()"&amp;gt;&amp;lt;ion-icon name="close"&amp;gt;&amp;lt;/ion-icon&amp;gt;&amp;lt;/button&amp;gt;
        &amp;lt;/ion-buttons&amp;gt;
    &amp;lt;/ion-toolbar&amp;gt;
&amp;lt;/ion-header&amp;gt;
&amp;lt;ion-content&amp;gt;
  &amp;lt;ion-list&amp;gt;
    &amp;lt;ion-item&amp;gt;
      &amp;lt;ion-label floating&amp;gt;Title&amp;lt;/ion-label&amp;gt;
      &amp;lt;ion-input type="text" [(ngModel)]="title"&amp;gt;&amp;lt;/ion-input&amp;gt;
    &amp;lt;/ion-item&amp;gt;
    &amp;lt;ion-item&amp;gt;
      &amp;lt;ion-label floating&amp;gt;Description&amp;lt;/ion-label&amp;gt;
      &amp;lt;ion-input type="text" [(ngModel)]="description"&amp;gt;&amp;lt;/ion-input&amp;gt;
    &amp;lt;/ion-item&amp;gt;
    &amp;lt;ion-item *ngIf="flag"&amp;gt;
      &amp;lt;ion-label floating&amp;gt;Due Date&amp;lt;/ion-label&amp;gt;
      &amp;lt;ion-input type="text" [(ngModel)]="dueDate"&amp;gt;&amp;lt;/ion-input&amp;gt;
    &amp;lt;/ion-item&amp;gt;
  &amp;lt;/ion-list&amp;gt;
    &amp;lt;button full ion-button color="secondary" (click)="saveItem()"&amp;gt;Save&amp;lt;/button&amp;gt; 
&amp;lt;/ion-content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How do we save our data?
&lt;/h3&gt;

&lt;p&gt;Our application is almost complete. The only problem is that it currently doesn't really save any data - every item you save will be wiped clean on reload. This can be fixed by accessing the local storage.&lt;br&gt;
Ionic provides a service called 'Storage' that can be used for saving data using a native SQLite database. However, if no such plugin is available, it falls back to the browser's local storage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Storage } from '@ionic/storage';
import {Injectable} from '@angular/core';

@Injectable()
export class Data {
  constructor(public storage: Storage){ }

  getData() {
    return this.storage.get('todos');  
  }

  save(data){
    this.storage.set('todos', data);
  }  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In home.ts, we can access our data service in the constructor to get our list of items from the local storage. This is done asynchronously, meaning the rest of the application will load the rest of the components and not wait for the completion of this request, thus blocking it in the process.&lt;br&gt;
The link to the sample application can be seen &lt;strong&gt;&lt;a href="https://github.com/SKing091/to-do-app"&gt;here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;If you want to build a hybrid application with a native touch regardless of the device it is running on, Ionic is the choice to go with. &lt;br&gt;
Ionic 4 breaks away from the restriction of using Angular as the base for your development, giving you the freedom to choose from all those cool frameworks available out there. For more details about Ionic and what they are cooking next, have a look at their &lt;strong&gt;&lt;a href="https://ionicframework.com/"&gt;website&lt;/a&gt;&lt;/strong&gt;.&lt;br&gt;
Releasing a great application in production doesn't mean the work is done. Any newly added feature may hurt your user base if it is not what they want. This can be avoided by using &lt;strong&gt;&lt;a href="https://configcat.com/"&gt;feature flags&lt;/a&gt;&lt;/strong&gt;, giving access to only a fraction of them for getting some live feedback. &lt;/p&gt;

&lt;p&gt;You can read more about ConfigCat on their &lt;strong&gt;&lt;a href="https://configcat.com/"&gt;website&lt;/a&gt;&lt;/strong&gt;,  or you could follow them on your &lt;strong&gt;&lt;a href="https://www.facebook.com/configcat"&gt;Facebook&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://twitter.com/ConfigCat"&gt;Twitter&lt;/a&gt;&lt;/strong&gt;, or &lt;strong&gt;&lt;a href="https://www.linkedin.com/company/configcat/"&gt;LinkedIn&lt;/a&gt;&lt;/strong&gt; accounts.&lt;/p&gt;

</description>
      <category>feature</category>
      <category>flag</category>
      <category>ionic</category>
      <category>configcat</category>
    </item>
    <item>
      <title>Space Invaders meet ConfigCat and MelonJS</title>
      <dc:creator>Manuel Popa</dc:creator>
      <pubDate>Mon, 21 Feb 2022 19:03:25 +0000</pubDate>
      <link>https://dev.to/manuelpopa/space-invaders-meet-configcat-and-melonjs-1o52</link>
      <guid>https://dev.to/manuelpopa/space-invaders-meet-configcat-and-melonjs-1o52</guid>
      <description>&lt;p&gt;Growing up as a child of the ’90s has always been a bitter-sweet kind of experience, but it certainly also came with a multitude of benefits. We’ve been exposed to countless priceless moments that have come and passed, moments that stand to make history and which may never be experienced again by newer generations. One such example of a beautiful lived-through historical moment is growing up with the fabled &lt;strong&gt;Space Invaders&lt;/strong&gt; game.&lt;br&gt;
 Simple yet memorable, Space Invaders made waves across the world and undoubtedly served as a catalyst for the revival of a previously stale and dying gaming industry that’s now priced at no less than 173.7 billion USD.&lt;/p&gt;
&lt;h2&gt;
  
  
  What we're going to do
&lt;/h2&gt;

&lt;p&gt;Nostalgia trip aside, the plan here is to rebuild “Space Invaders” in MelonJS while also taking advantage of ConfigCat's &lt;strong&gt;&lt;a href="https://configcat.com/"&gt;feature flag management service&lt;/a&gt;&lt;/strong&gt; to toggle your player's ship from the default one to another, more custom version. &lt;/p&gt;
&lt;h2&gt;
  
  
  What is MelonJS​ ?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5Gw4Jlg_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xu6tkqt3f7qmtq0egi9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5Gw4Jlg_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xu6tkqt3f7qmtq0egi9.png" alt="MelonJs" width="808" height="410"&gt;&lt;/a&gt;&lt;br&gt;
Well, silly naming scheme aside (which may or may not give you a craving for melons), it’s an:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;actively maintained&lt;/li&gt;
&lt;li&gt;open-source&lt;/li&gt;
&lt;li&gt;JS-powered game engine that’s licensed under MIT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Personally, I’d go for MelonJS 2&lt;/strong&gt;, as it’s a modern remake of the engine that's perfectly adapted to support ES6 class, inheritance, as well as many other goodies. If you want to learn more about what it can do, check out their docs right &lt;a href="https://melonjs.github.io/melonJS/docs/"&gt;here&lt;/a&gt;. &lt;/p&gt;
&lt;h2&gt;
  
  
  What are Feature Flags? &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d83GAxdk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d46a8742tulrty3p9yw7.png" width="112" height="74"&gt;
&lt;/h2&gt;

&lt;p&gt;In short, you can visualize a feature flag as a switch that’s used to activate or deactivate certain functionalities that may be present in your application. &lt;/p&gt;
&lt;h4&gt;
  
  
  Here are some examples of why you may want to use feature flags:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;give early access to new features to only a select few&lt;/li&gt;
&lt;li&gt;targeting specific demographics&lt;/li&gt;
&lt;li&gt;various other testing purposes&lt;/li&gt;
&lt;li&gt;releasing things in a more ordered and stable manner&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Why use ConfigCat? &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ArejvH5a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6tw5olfyidvst8ongn5.png" alt="cat" width="64" height="78"&gt;
&lt;/h2&gt;

&lt;p&gt;What makes ConfigCat attractive is that they offer a very balanced &lt;strong&gt;&lt;a href="https://configcat.com/#pricing"&gt;forever-free plan&lt;/a&gt;&lt;/strong&gt;, which includes a plethora of things, including &lt;strong&gt;their entire security stack&lt;/strong&gt; (while most other competitors would have you pay extra for those). This eliminates any artificial incentive for you to upgrade unless your business organically scales to new requirements.&lt;/p&gt;

&lt;p&gt;You could technically create your own in-house feature flag service, but it would make more financial sense to just use an already existent one like &lt;a href="https://configcat.com/#pricing"&gt;ConfigCat’s&lt;/a&gt;. &lt;/p&gt;
&lt;h2&gt;
  
  
  Time to build Space Invaders!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QUOvFxjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3t4gvzmdm8gh6ld0g5dv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QUOvFxjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3t4gvzmdm8gh6ld0g5dv.png" alt="spaceInvaders" width="880" height="266"&gt;&lt;/a&gt;&lt;br&gt;
The version of Space Invaders that we’ll be building won’t be anything truly fancy, just your average, stripped-down base game with no extra bells and whistles. We’ll have a set of ships arranged in an 8 by 4 grid rushing toward our ship. &lt;/p&gt;
&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;

&lt;p&gt;The easiest way to start your project is by getting the &lt;strong&gt;&lt;a href="https://github.com/melonjs/es6-boilerplate/archive/refs/heads/main.zip"&gt;ES6 boilerplate&lt;/a&gt;&lt;/strong&gt; provided by MelonJS. After that just trim your excess folders and files, and the result should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src
└── data
|    ├── img
└── js
|    ├── renderables
|    └── stage
├── index.js
├── index.css
├── index.html
├── manifest.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;br&gt;
Here's the &lt;strong&gt;&lt;a href="https://github.com/ManuelPopa/melonJS_invaders_game"&gt;repo link&lt;/a&gt;&lt;/strong&gt; of the finished game, in case you want to follow along. &lt;/p&gt;
&lt;h3&gt;
  
  
  Building the game
&lt;/h3&gt;

&lt;p&gt;To start using MelonJS, we’ll just add the following line to the top of each file where we’ll need to use its functionalities:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as me from 'melonjs/dist/melonjs.module.js';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;For this project, we’ll add three more files under the js folder: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;constants.js&lt;/strong&gt; - used to define things like laser’s width and height&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;laser.js&lt;/strong&gt; - used to define the Laser entity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;enemy-manager.js&lt;/strong&gt; - used to manage the creation and movement of the enemy ships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The entry point for your project is the &lt;strong&gt;index.js&lt;/strong&gt; file where the canvas is prepared and all the prerequisites for the game are preloaded by the &lt;code&gt;&lt;/code&gt;onReady()&lt;code&gt;&lt;/code&gt; method:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;me.device.onReady(() =&amp;gt; {
    setTimeout(() =&amp;gt; {
        if (!me.video.init(
                1218, 562,
                {parent: 'screen', scale: 'auto', scaleMethod: 'flex-width'})) {
            alert('Your browser does not support HTML5 canvas.');
            return;
        };
        me.audio.init('mp3,ogg');
        me.loader.crossOrigin = 'anonymous';
        me.loader.preload(DataManifest, function() {
            me.state.set(me.state.PLAY, new PlayScreen());

            me.pool.register('player', PlayerEntity);
            me.pool.register('ships', EnemyEntity);
            me.pool.register('laser', Laser);

            me.state.change(me.state.PLAY);
        });
    }, 5000);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;br&gt;
Under the renderables folder we have two files important for the movement and interactions of the ships soon to be battling each other:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;enemy.js&lt;/strong&gt; - used to define EnemyEntity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;player.js&lt;/strong&gt; - used to define PlayerEntity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The epic battle will be staged in the stage folder, inside the &lt;strong&gt;play.js&lt;/strong&gt; file where we have the &lt;code&gt;&lt;/code&gt;onResetEvent()&lt;code&gt;&lt;/code&gt;, &lt;code&gt;&lt;/code&gt;onDestroyEvent()&lt;code&gt;&lt;/code&gt; and &lt;code&gt;&lt;/code&gt;checkIfLoss()&lt;code&gt;&lt;/code&gt; methods which will dictate the way our game will work.&lt;/p&gt;

&lt;p&gt;All the images we’ll need can be found in the &lt;strong&gt;"data/img folder"&lt;/strong&gt; and we’ll use them in the &lt;strong&gt;manifest.js&lt;/strong&gt; file as such:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const DataManifest = [
    {name: 'player', type: 'image', src: 'data/img/player.png'},
    {name: 'player2', type: 'image', src: 'data/img/player2.png'},
    {name: 'ships', type: 'image', src: 'data/img/ships.png'},
    {name: 'bg', type: 'image', src: 'data/img/bg.jpg'}
];

export default DataManifest;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;
&lt;h3&gt;
  
  
  Tips and Tricks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If you want to add a custom background picture to the game, use the following code to the &lt;code&gt;&lt;/code&gt;OnResetEvent()&lt;code&gt;&lt;/code&gt; method, located in the &lt;strong&gt;play.js&lt;/strong&gt; file: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; me.game.world.addChild(new me.ImageLayer(0, 0, {
    image: "bg", 
    repeat: "repeat",
    z: 0
 }), 0);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One issue that you may encounter is with the game’s resetting functionality when calling the &lt;code&gt;&lt;/code&gt;checkIfLoss()&lt;code&gt;&lt;/code&gt; function. The bug seems to be caused by the &lt;code&gt;&lt;/code&gt;bounds.bottom&lt;code&gt;&lt;/code&gt; argument which may sometimes equal infinity. You can easily go around this bug by just adding the following check at the end of the first if statement in the &lt;strong&gt;enemy-manager.js&lt;/strong&gt; file - at the time of writing, this was at line 40.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (me.state.current() instanceof PlayScreen) {
me.state.current().checkIfLoss(bounds.bottom);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;In the end, if all goes well and the Gods of coding are merciful, you should be able to see this: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I8HysABw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bjx3c0fquxzwqvash564.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I8HysABw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bjx3c0fquxzwqvash564.gif" alt="gif1" width="880" height="424"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Using ConfigCat's Feature Flags in Space Invaders
&lt;/h3&gt;

&lt;p&gt;Let's say that I want to change the main ship with a custom version to be displayed to a specific audience. The easiest way to do this without having to change the code and make another deployment of the new version is to implement a feature flag, which can be switched on and off with ease. &lt;/p&gt;

&lt;p&gt;I intend to show the custom version of the ship only if the evaluation of the flag is true. And since the application is written in Javascript, I’ll choose &lt;strong&gt;&lt;a href="https://configcat.com/docs/sdk-reference/js"&gt;ConfigCat's Javascript SDK&lt;/a&gt;&lt;/strong&gt;, for which the process of installing is fairly straightforward and well &lt;strong&gt;&lt;a href="https://configcat.com/docs/"&gt;documented&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Just fire up &lt;strong&gt;npm&lt;/strong&gt; and run &lt;code&gt;&lt;br&gt;
&lt;br&gt;
&lt;/code&gt;&lt;code&gt;npm install configcat-js&lt;/code&gt;&lt;code&gt;&lt;br&gt;
&lt;br&gt;
&lt;/code&gt;, after which just import it in &lt;strong&gt;constants.js&lt;/strong&gt; file via the following line:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import * as configcat from "configcat-js";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;The next thing that you need to do is to quickly head over to ConfigCat’s registration page and &lt;a href="https://app.configcat.com/"&gt;create a free account&lt;/a&gt; for yourself. After which you’re all set to create your first feature flag. I named mine &lt;strong&gt;"isMyFirstFeatureEnabled"&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v15aXZ9z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5u3n6bfj6dhu3ajg6uge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v15aXZ9z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5u3n6bfj6dhu3ajg6uge.png" alt="feature flag" width="880" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm now free to go to &lt;strong&gt;constants.js&lt;/strong&gt; and add my SDK key (which you can grab from the &lt;a href="https://app.configcat.com/"&gt;ConfigCat Dashboard&lt;/a&gt; where you created the flag earlier). Once in the dashboard, you'll see a button in the upper right-hand corner called “View SDK Key”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I then create the client like this:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  let flag ;
  const client = configcat.createClient(sdkKey);
  const getFlag = () =&amp;gt; flag;
  client.getValue("isMyFirstFeatureEnabled", false, value =&amp;gt; {
     flag=value;
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;Now that the client is in order, we should now hop in the &lt;strong&gt;player.js&lt;/strong&gt; file, import the &lt;code&gt;&lt;/code&gt;getFlag()&lt;code&gt;&lt;/code&gt; method from &lt;strong&gt;constants.js&lt;/strong&gt; and use it to load the player with a new ship depending on the flag’s value: &lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  if (getFlag()) {
    image = me.loader.getImage("player2");  
  } else {
    image = me.loader.getImage("player"); 
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;Last but certainly not least, all that’s left to do now is to use the &lt;a href="https://app.configcat.com/"&gt;ConfigCat Dashboard&lt;/a&gt;, flip the flag to "true" and then reload the game. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BAM! The result should be something like this:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aOMDNP09--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xz3g4m0v3lisv4erboco.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aOMDNP09--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xz3g4m0v3lisv4erboco.gif" alt="gif2" width="880" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion​
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MelonJS is a powerful JS game engine&lt;/strong&gt; and as a testimony to this stands the vast &lt;a href="https://melonjs.github.io/melonJS/docs/"&gt;documentation&lt;/a&gt; that you need to read in order to unleash its true power. It certainly can help you in case you want to have a chance at making the next big game hit. &lt;strong&gt;Feature Flags can be outstandingly scalable and useful&lt;/strong&gt;, and I’m glad that I found &lt;strong&gt;&lt;a href="https://configcat.com/"&gt;ConfigCat&lt;/a&gt;&lt;/strong&gt; to help me out with this. &lt;/p&gt;

&lt;p&gt;Here’s the &lt;strong&gt;&lt;a href="https://github.com/ManuelPopa/melonJS_invaders_game"&gt;git repo link&lt;/a&gt;&lt;/strong&gt; in case you want to check out this tiny Space Invaders remake and I hope you that you'll get to relive some nice childhood memories playing it. &lt;/p&gt;

&lt;p&gt;If you are looking for more articles like this, make sure to check out &lt;a href="https://configcat.com/blog/"&gt;ConfigCat’s blog posts&lt;/a&gt; or you could follow them on your &lt;a href="https://www.facebook.com/configcat"&gt;Facebook&lt;/a&gt;, &lt;a href="https://twitter.com/ConfigCat"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/company/configcat/"&gt;LinkedIn&lt;/a&gt; accounts.&lt;/p&gt;

</description>
      <category>configcat</category>
      <category>javascript</category>
      <category>spaceinvaders</category>
      <category>melonjs</category>
    </item>
  </channel>
</rss>
