3

Here's an example of some code I picked up for an Angular2 tutorial by Max Schwarzmueller on YouTube: https://www.youtube.com/playlist?list=PL55RiY5tL51olfU2IEqr455EYLkrhmh3n.

import {Injectable} from "angular2/core";
import {CONTACTS} from "./mock-contact";

@Injectable()

export class ContactService {

    getContacts() {
        return Promise.resolve(CONTACTS);
    }

    insertContact(contact: Contact) {
        Promise.resolve(CONTACTS)
            .then(
                (contacts: Contact[]) => contacts.push(contact)
            );
    }

}

In this example, the CONTACTS object is static JSON. A promise isn't necessary here, but was used to show usage of a service in the real world.

I pretty much understand it, but I'm trying to migrate this idea into a service where I'm using an observable instead of a promise.

I want to make a change to the CONTACTS array, and then have the Observable emit .then again to tell all the observers to do their thing one more time.

On an observable, what would be analogous to Promise.resolve here? The documentation for RxJS observables is a lot to wade through.

If this is just a dumb idea, or there's a better way, please let me know.

BBaysinger
  • 6,614
  • 13
  • 63
  • 132
  • *"the CONTACTS object is static JSON."* No, it isn't. JSON is a *textual notation* for data exchange. [(More.)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Dec 19 '16 at 07:44
  • Ok. I guess what I meant was that it was pulled from a local js file as an array, and not a REST api. What's a better way to say that? – BBaysinger Dec 19 '16 at 07:53
  • 1
    It doesn't matter where it comes from. It's just an array. – T.J. Crowder Dec 19 '16 at 07:58
  • Ok, but it is an array in JSON format. – BBaysinger Dec 19 '16 at 08:20
  • 1
    That's the point: No, it isn't. It's an array. It was in JSON format (text) before it was parsed, but then it was parsed, and is no longer JSON. It's an array. I can tell because you've called `push` on it. Strings (text) don't have a `push` method. – T.J. Crowder Dec 19 '16 at 08:59

2 Answers2

5

With

getContacts() {
  return Observable.of(CONTACTS);
}

the observable will complete after it emitted the CONTACTS.

See also http://paqmind.com/posts/rxjs-error-and-completed-events-demystified/

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
1

The following is functioning code that works as far as my original question goes. I've replaced the JSON formatted array from CONTACTS with data pulled from a local JSON file, and I'm dealing with products instead of contacts.

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Product } from './product';
import { Observable } from 'rxjs/Rx';

@Injectable()

export class ProductsService {

    private _productsUrl = "./products.json";    
    private _productObservable: Observable<Product[]>;
    private _products: Product[];

    constructor(private _http: Http) {

    }

    getProducts() : Observable<Product[]> {

        this._productObservable = this._http.get(this._productsUrl)

            .map((response:Response) => {

                if (this._products == null) 
                {
                    this._products = response.json();
                }
                return this._products;

            })
            .catch((error:any) => Observable.throw(error || 'Server error'));


        return this._productObservable;

    }

    deleteProduct()
    {
        this._products.pop();

        return Observable.of(this._products);
    }

}
BBaysinger
  • 6,614
  • 13
  • 63
  • 132