Posts tagged Ionic Framework

The Best Phone for Ionic Framework Development

I have found the one phone that every mobile developer should have on their desks. So what is this remarkable device and why should you add another one one to the many of devices any good mobile developer already has? Well let me dive into that, but first, let me show you the glory that is the BLU Grand XL.

smartphone-blu-grand-xl-dual-sim-3g-tela-5-5-hd-cpu-4core-c-m--8mp-5mp-pretoThis puppy is about the size of an iPhone 6/7 Plus, and a little bit thicker and a noticeable amount heavier. The one I picked up is running the latest. at the time, version of Android 7 (which is why I stumbled across this gem). I picked mine up for $100 unlocked at BestBuy but I have been seeing them show up for less online as well.

The screen, device feel and size all make it a pretty decent device to have to pick up and set down all the time. The screen is fairly responsive so that doesn’t complicate any testing and it easily hooks into Windows and MacOS out of the box for USB debugging and deployments.

But the magic occurs when you look at the device specs and start testing your apps on it.


Category Value

CPU

Mediatek MT6580 Quad-core 1.3Ghz
RAM 1GB
Storage 8GB
Network

3G (GSM/HSPA)

Don’t be fooled, that quad core 1.3Ghz processor is not as powerful as it sounds. For the most part it seems to run Android 7 ok, but there isn’t much left over for apps. But there is where the magic occurs for us developers, that processor and amount of RAM is almost the perfect modern day worst case performance scenario. Here at Resgrid we’ve been developing against the Ionic Framework since around 2014’ish and developing on the hybrid stack mean performance is a big concern, but also something that can be difficult to really test and gauge.

Us developers usually have pretty good phones, which means our apps usually run very well. But what are your users using? Prepaid phones and now phones like the BLU Grand XL are out there and very affordable. A lot of people out there using phones a few years old and a lot of people have gotten off the “upgrade every year or 2” train.

Because of the nature of the Resgrid app, targeting emergency management and first responders, we have a pretty high target in terms of performance (our goal is a usable app within 3 seconds), but given the fact that we are at the mercy of the device and browser on that device it can be a difficult target to hit across the board.

But if you can get your app working well on the BLU Grand XL, it’s going to work well on so many other devices. When we first loaded our app on that puppy (in prod mode with aot) it took almost 18 seconds to be fully usable. Because of this we implemented lazy loading, removed plugins and packages and so far have that time down to 12 seconds and still have a way to go.

If you’re a First Responder or know one check out Resgrid which is a SaaS product utilizing Microsoft Azure, providing logistics, management and communication tools to first responder organizations like volunteer fire departments, career fire departments, EMS, search and rescue, CERT, public safety, disaster relief organizations.

Ionic Framework: Uncaught (in promise): removeView was not found

During our rewrite efforts to move our existing Ionic 1 applications to Ionic 3 we developed a pattern that looks like this:

export class ChatRoomPage {
  public room: any;
  public loader: Loading;
  public roomSid: string;

  constructor(public navCtrl: NavController, private chatProvider: ChatProvider,
    private consts: Consts, public loadingCtrl: LoadingController, private params: NavParams,
    @Inject(APP_CONFIG_TOKEN) private appConfig: AppConfig) {

    this.loader = this.loadingCtrl.create({
      spinner: 'hide',
      content: 'Loading Please Wait...'
    });
  }

  ionViewDidLoad() {
    this.loader.present();
    this.fetch(null);
  }

  private fetch(refresher) {
    this.chatProvider.getRoomBySid(this.roomSid).subscribe(
      data => {
        this.loader.dismiss();
        this.room = data;
      });
  }
}

The pattern was pretty easy, our Loading popover didn’t change per instance, so we setup it in the controller. We also had pages were we setup the Loading controller in the ionViewDidLoad() method as well. But during testing, were pages were loading multiple times we started to notice this error.

2017-08-04 17_59_35-Microsoft Edge

Extremely frustrating, every time we nav’ed back to a view we could not figure out what was causing the issue, was it navigation, which has had some issues? Nope, it’s the dang loading popover. We made changes, based in part from this thread, and our resulting code now looks like this.

export class ChatRoomPage {
  public room: any;
  public loader: Loading;
  public roomSid: string;

  constructor(public navCtrl: NavController, private chatProvider: ChatProvider,
    private consts: Consts, public loadingCtrl: LoadingController, private params: NavParams,
    @Inject(APP_CONFIG_TOKEN) private appConfig: AppConfig) {
      this.room = {};
  }

  ionViewDidLoad() {
    this.fetch(null);
  }

  private fetch(refresher) {
    this.loader = this.loadingCtrl.create({
      content: 'Loading Please Wait...'
    });

    this.loader.present().then(() => {
      this.chatProvider.getRoomBySid(this.roomSid).subscribe(
        data => {
          this.room = data;

          this.loader.dismissAll();
          this.loader = null;
        },
        err => {
          this.room = {};

          this.loader.dismissAll();
          this.loader = null;
        });
    });
  }
}

The issue is when you call LoadingController.dismiss() or LoadingController.dismissAll() the view that the loading controller creates for your popover is destroyed and cannot be reused. So to be able to call LoadingController.present() again you need to call loadingController.create() beforehand.

Additionally there can be race condition between LoadingController.present() and LoadingController.dismiss(), so another recommendation is to wait for the LoadingController.present() promise to return before running into any instance that may quickly (i.e. in an error case) call dismiss().

If you’re a First Responder or know one check out Resgrid which is a SaaS product utilizing Microsoft Azure, providing logistics, management and communication tools to first responder organizations like volunteer fire departments, career fire departments, EMS, search and rescue, CERT, public safety, disaster relief organizations.

Angular2/Ionic2: No provider for ….

When your developing an angular 2/ionic 2 application and you get the the following error:

EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in :0:0
ORIGINAL EXCEPTION: No provider for UserService!
ORIGINAL STACKTRACE:
Error: DI Exception
    at NoProviderError.BaseException [as constructor] (http://localhost:8100/build/js/app.bundle.js:2300:23)
    at NoProviderError.AbstractProviderError [as constructor] (http://localhost:8100/build/js/app.bundle.js:27491:16)
    at new NoProviderError (http://localhost:8100/build/js/app.bundle.js:27528:16)
    at ReflectiveInjector_._throwOrNull (http://localhost:8100/build/js/app.bundle.js:28516:19)
    at ReflectiveInjector_._getByKeyDefault (http://localhost:8100/build/js/app.bundle.js:28544:25)
    at ReflectiveInjector_._getByKey (http://localhost:8100/build/js/app.bundle.js:28507:25)
    at ReflectiveInjector_.get (http://localhost:8100/build/js/app.bundle.js:28316:21)
    at ElementInjector.get (http://localhost:8100/build/js/app.bundle.js:29890:48)
    at ElementInjector.get (http://localhost:8100/build/js/app.bundle.js:29890:48)
    at ReflectiveInjector_._getByKeyDefault (http://localhost:8100/build/js/app.bundle.js:28541:24)
ERROR CONTEXT:
[object Object]

Your module exists, it’s setup and your import is working. So what’s up? You need to make it available for your application. In your app.ts you have 2 approach’s add a new paramter to your @Component called providers that takes an array of modules.

Angular 2 (non-Ionic)

@Component({ 
  templateUrl: “build/app.html”,
  providers: [UserService],
})

For Ionic you can also just pass it into the ionicBootstrap function, the second parameter to that is an array of modules:

ionicBootstrap(ConnectApp, [UserService]);

Hope this helps!

Go to Top