How to return an observable in Angular 2

1

I have the following problem, I have several controls that subscribe to an http service that returns the data of a project according to the project code, calls of this type:

this.proyectosService.getByCodigo('xxx').subscribe(response => {
    // hacer algo
});

the service method is nothing special:

public getByCodigo(codigo: string) {
    return this.http.get(this.url + codigo).map(response => response.json());
}

The issue is that I'm seeing that too many requests are made in a row, to the same url so to optimize times it occurs to me that I could save the last returned object in the memory of the service and check with the server to check if the requested object is the one that I have in memory (compare the project code), the problem is that I do not know how to return in case it already has in memory the object as an observable so that it is transparent for the controls that subscribe to the service , the idea is to do something like this:

 public getByCodigo(codigo: string) {
    if (this.ultimoProyecto.codigo === codigo) {
        // aqui el problema como devuelvo los datos
    } else {
        return this.http.get(this.url + codigo).map(response => {
            this.ultimoProyecto = response.json() // actualizo referencia al ultimo devuelto
            return response.json();
        });
    }
}
    
asked by Ricardo D. Quiroga 02.08.2017 в 23:35
source

2 answers

1

I auto respond with the solution that I have found so far and it has worked for me, in the end it was only to return an observable.

public getByCodigo(codigo: string) {
    if (this.ultimoProyecto.codigo === codigo) {
        return new Observable((observer) => {
                return observer.next(this.ultimoProyecto);
            });
    } else {
        return this.http.get(this.url + codigo).map(response => {
            this.ultimoProyecto = response.json() // actualizo referencia al ultimo devuelto
            return response.json();
        });
    }
}
    
answered by 07.08.2017 / 02:25
source
2

Use an associative array and if it already exists the code returns the value of the index according to the code already stored in it, but create it, insert it and return it.

import { EventEmitter, Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';

import { environment } from './../../environments/environment';

@Injectable()
export class ProyectosService {

  private baseUrl: string = environment.baseUrl;
  private ultimoProyectoConCodigo = [];

  constructor(private http: Http) {}

  public getByCodigo(codigo: string): Observable<any> {
      return this.ultimoProyectoConCodigo[codigo] || this.ultimoProyectoConCodigo[codigo] = 
        this.http.get(this.baseUrl+codigo)
          .map((res: Response) => res.json())
          .catch((error: any) => Observable.throw(error.json().error || 'Server error'));
  }

 }
  

Another much better option would be to use Redux.js: link .

    
answered by 03.08.2017 в 00:02