How does HTTP error-handling work with observables?

I see a lot of tutorials doing something like this:

http.get("...").subscribe(
  success => console.log('hello success'),
  error => console.log('bye error')
);

I don’t know how this works, since there aren’t any types or anything, however I tried to do that myself and I end up that the request always goes into success, even if I have an error. What is the problem?

Troublemaker:

this.memberService.create(this.currentMember)
      .subscribe(
        success => {
          let mem: Member = success.json() as Member;
          if (this.selectedOrganization) {
            this.addMemberToOrganization(mem);
          } else if (this.selectedServiceProvider) {
            this.addMemberToServiceProvider(mem);
          } else {
            this.toastsService.error("lbl_users_service_provider_and_organization_undefined");
          }
        },
        error => console.log(error)
      );

Create-Method in the memberService:

  create(member: Member): Observable<any> {
    return this.http
      .post(this.RESOURCE_BASE_URL, member)
      .map(response => {
        if (response.status === 200) this.toastsSerivce.success(this.translateService.instant('lbl_users_member_created'));
        return response;
      })
      .catch(error => this.toastsSerivce.error(this.translateService.instant('lbl_users_member_create_failed')));
  }

I even catch the error, but the subscribe part doesn’t seem to care.
It fails at success.json(), because if there is an error, there is no json. But if there is an error, I want it to call the error =>... instead of the success. Any advice is highly appreciated.

observables for api request in angular2

Hi I’m implementing a observable to make a get to my skill api and I have a problem in the moment to map the data requested.
my array in the end of request keep null, I think that my problem is in extractData().

This is my service:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Skill } from './skill';

@Injectable()
export class CatalogService {
    private api = 'http://127.0.0.1:8000/api/';
    constructor(private http: Http) {}

    getSkill(): Observable<Skill[]> {
        return this.http.get(this.api + "skill")
            .map(this.extractData)
            .catch(this.handleError);
    }

    private extractData(res: Response) {
        let body = res.json();
        return body.data || {};
    }

    private handleError(error: Response | any) {
        // In a real world app, you might use a remote logging infrastructure
        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }
}

Here is my .ts where I call my service

import { Component, OnInit } from '@angular/core';
import {CatalogService} from './catalog.service';
import {Skill} from './skill';
@Component({
    selector: 'app-catalog',
    templateUrl: './catalog.component.html',
    styleUrls: ['./catalog.component.css']
})
export class CatalogComponent implements OnInit {
    skills:Skill[];
    errorMessage:string;
    mode = 'Observable';
    constructor(private catalogService: CatalogService) { }

    ngOnInit() {
        this.getSkill();
    }
    getSkill() {
        this.catalogService.getSkill()
            .subscribe(
                skills => this.skills =skills,
                error =>  this.errorMessage = <any>error);
    }
}

This is a get returned by my api skill:

[
    {
        "id": 2,
        "experience": "null",
        "typeskill": 1,
        "profile": 2
    },
    {
        "id": 3,
        "experience": "null",
        "typeskill": 1,
        "profile": 3
    }
]

I appreciate the help to solve this issue.

Putting two async subscriptions in one Angular *ngIf statement

I have the following in my component template:

<div *ngIf="user$ | async as user>...</div>

Within the above div I would like to use the async pipe to subscribe to another observable only once, and use it just like user above throughout the template. So for instance, would something like this be possible:

<ng-template *ngIf="language$ | async as language>
<div *ngIf=" user$ | async as user>
  <p>All template code that would use both {{user}} and {{language}} would go in between</p>
  </div>
</ng-template>

Angular – RxJS – Return observable when a value is true

I have this function. I want these lines:

this.setHeaders(url);
return this.request(url, options);

to execute when this.refreshTokenService.wait === false.

private catchErrors(url: string | Request, options?: RequestOptionsArgs) {

    return (res: Response) => {
        if (res.status === 401 || res.status === 403) {

            if (this.refreshTokenService.wait === false) {
                console.log('FIRST');
                this.refreshTokenService.wait = true;
                return this.refreshTokenService.refreshToken(localStorage.getItem('JWToken'))
                    .flatMap((result: any) => {
                        // if got new access token - retry request
                        localStorage.setItem('JWToken', JSON.parse(result._body).token);
                        this.setHeaders(url);
                        this.refreshTokenService.wait = false;
                        return this.request(url, options);
                    })
            } else {
                // TODO here
                this.setHeaders(url);
                return this.request(url, options);

            }
        } else {
            Observable.throw(res);
        }
    };
}

But the function wants only to return observable or promise to run smoothly.

Thank you

request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {

    if (typeof url === 'string') {
        if (!options) {
            options = {headers: new Headers()};
        }
        this.setHeaders(options);
    } else {
        this.setHeaders(url);
    }

    return super.request(url, options).catch(this.catchErrors(url, options));
}

Angular – Watch localStorage value inside a directive

I have a service that has this function

getCurrentUserPermissions() {
    return JSON.parse(localStorage.getItem('currentUserPermissions'));
}

Now I create a directive to show and hide menus

*hasPermissions="['stations','users']"

Directive

import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core';
import {SiteService} from "../services/site.service";

@Directive({selector: '[hasPermissions]'})
export class HasPermissionsDirective {

@Input("hasPermissions") conditions: string[];

constructor(private templateRef: TemplateRef<any>,
            private viewContainer: ViewContainerRef,
            private siteService: SiteService
) {
}

ngOnInit() {
    let BreakException = {};
    let result: boolean = true;
    let currentUserPermissions = this.siteService.getCurrentUserPermissions();

    try {
        this.conditions.forEach(function (keyCondition) {
            if (currentUserPermissions[keyCondition] !== true) {
                result = false;
                throw BreakException;
            }
        });
    } catch (e) {
        if (e !== BreakException) throw e;
    }

    if (result) {
        this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
        this.viewContainer.clear();
    }
}
}

How can I watch the this.siteService.getCurrentUserPermissions() for changes? Because now i have to refresh the page to rerender the directive to work, if I change the permissions

Async pipe does not show my observable

In code below page shows before-null-after, but console shows ‘2’. For some reason page is not updated… What do I do wrong?

import {Component, OnInit} from '@angular/core';
import {Http} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map'


@Component({
  template: `before-{{searchResult | async | json}}-after`,
  selector: 'app-root',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {

  searchResult: Observable<String[]>;

  searchTerms = new Subject<String>();

  constructor(private http: Http) {

  }

  ngOnInit(): void {
    console.error(JSON.stringify(['aaaa', 'bbbb']));

    this.searchResult = this.searchTerms
      .switchMap(term => this.http.get('/assets/async.json').map(response => response.json() as String[]));
    this.searchResult.subscribe(next => console.error(next.length));

    this.searchTerms.next('sss');
  }
}

“@angular/core”: “^4.0.0”

Angular 4 Subscribing to observable is not updating after change

I have a service with an observable which is being subscribed to via a component. This seems to work as the subscriber is showing the initial value. I have another component which is then updating the observable however the new value does not get shown.

Service:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of'; 

@Injectable()

export class BannerService {

    banners$: Observable<any[]> = Observable.of([]);

    getBanners(): Observable<any[]> {
        return this.banners$;
    }

    setBanners(banners: any[]): void {
        this.banners$ = Observable.of(banners);
    }

}

Component with subscriber:

import { Component, ViewEncapsulation, OnInit } from '@angular/core';

import { BannerService } from './../banner/banner.service';

@Component({
    selector: '.banner',
    templateUrl: './banner.component.html',
    styleUrls: ['./banner.component.sass'],
    encapsulation: ViewEncapsulation.None
})

export class BannerComponent implements OnInit {

    constructor(private bannerService: BannerService){}

    ngOnInit() {
        this.bannerService.banners$.subscribe(banners => {
            console.log(banners);
        });

    }
}

Component with setter:

import { Component, ViewEncapsulation, OnInit } from '@angular/core';

import { BannerService } from './../banner/banner.service';

@Component({
    selector: '.home-component',
    templateUrl: './home.component.html',
    styleUrls: ['./home.component.sass'],
    encapsulation: ViewEncapsulation.None
})

export class HomeComponent implements OnInit {

    data = {
        banners: [
            {
                title: 'Title 1',
                image: '../images/image1.jpg'
            },
            {
                title: 'Title 2',
                image: '../images/image2.jpg'
            },
            {
                title: 'Title 3',
                image: '../images/image3.jpg'
            }
        ]
    }

    constructor(private bannerService: BannerService){}

    ngOnInit(): void {
        this.bannerService.setBanners(this.data.banners);
    }

}

Any help would be really appreciated, I’ve tried a bunch of different things and can’t get it working.

Angular – Subscribe to route.queryParams

I’ve got this in my ngOnInit

ngOnInit(): void {

    this.sub = this.route.queryParams.subscribe((params: any) => {
        this.data = {...params};
        this.stationsService.getStations(this.data).subscribe((res: any) => {
            this.stations = res.data.stations
        })
    });
}

and also have this delete function

deleteMass() {
    let array: any = manipulateSelections(this.selected, this.stations);
    this.stationsService.deleteStations(array).subscribe((res: any) => {
        this.data.random = Math.random();
        this.router.navigate([], {queryParams: this.data });
    })
}

What I’m doing. Every time I delete stations I create a random number to change me route to make the first observable runs again. Can you suggest a better way. This seems very bad practice.