Posts tagged Angular

Angular 4/5 HttpClient Http failure during parsing Error

0

When upgrading my Ionic 3 app to 3.9.0 I also took the opportunity to update the older Http provider to the highly touted HttpClient one. For the most part this worked well and saved some nasy stuff I had in every one of my calls to force it to a JSON response and add the AuthHeader, as the old Http provider didn’t support interceptors. But I did run into a problem:

2017-11-09 13_57_08-Developer Tools - http___localhost_8100_

After some quick googling the issue appears to be when you have a 2xx response from a web server with an empty body tag. For example if your save data to the server and using the Http Status Code 201 to let the client know it was added, instead of having a response object, you will get this error when using HttpClient in Angular 4 and Angular 5.

You can fix it by adding a text type to each call, but that is a really awful way of doing it. But compeek’s reply to this issue has a temp fix, an interceptor!

import { Injectable, NgModule } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { HTTP_INTERCEPTORS } from '@angular/common/http';

@Injectable()
export class EmptyResponseBodyErrorInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req)
            .catch((err: HttpErrorResponse) => {
                if (err.status >= 200 && err.status < 300) {
                    const res = new HttpResponse({
                        body: null,
                        headers: err.headers,
                        status: err.status,
                        statusText: err.statusText,
                        url: err.url
                    });

                    return Observable.of(res);
                } else {
                    return Observable.throw(err);
                }
            });
    }
}

@NgModule({
    providers: [
        { provide: HTTP_INTERCEPTORS, useClass: EmptyResponseBodyErrorInterceptor, multi: true }
    ]
})
export class HttpInterceptorModule { }

You can then import HttpInterceptorModule into the App’s Module, problem solved! Hopefully they will get a fix into the Angular HttpClient soon and we can all remove this workaround but until then….

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