que - observables angular 5
Mecanografiado angular-observable: ¿cómo cambiar su valor? (4)
De los comentarios en mi otra respuesta (conservada, ya que puede ser útil para alguien), parece querer aprovechar el poder de algo para emitir valores a lo largo del tiempo .
Como propuso DOMZE, use un Asunto, pero aquí hay un ejemplo (trivial) que muestra cómo podría hacerlo. Aunque evidentemente hay algunos escollos que se deben evitar al usar el Sujeto directamente , lo dejo en tus manos.
import { Component, NgModule } from ''@angular/core''
import { BrowserModule } from ''@angular/platform-browser''
import { Observable, Subject } from ''rxjs/Rx'';
@Component({
selector: ''my-app'',
template: `
<div>
<h2>Open the console.</h2>
</div>
`,
})
export class App {
constructor() {}
let subject = new Subject();
// Subscribe in Component
subject.subscribe(next => {
console.log(next);
});
setInterval(() => {
// Make your auth call and export this from Service
subject.next(new Date())
}, 1000)
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
En mi humilde opinión, para este escenario, no veo por qué un simple Servicio / Observable no es suficiente, pero eso no es de mi incumbencia.
Lectura adicional: Angular 2 - ¿Comportamiento comportamiento vs observable?
Tal vez me esté perdiendo algo. No puedo encontrar un tutorial simple para Observable y su sintaxis. Estoy trabajando con Angular, necesito llamar a una función (definida en un componente) desde un servicio. Leí esta solution . Pero no puedo averiguar cómo cambiar el valor en el Observable creado en el servicio (tal vez la creación no sea el mejor método).
Tengo un componente como en la solución:
@Component({
selector: ''my-component'',
...
)}
export class MyComponent {
constructor(myService:MyService) {
myService.condition.subscribe(value => doSomething(value));
}
doSomething(value) {
if (value) // do stuff
else // other stuff
}
}
y este es mi servicio
import { Injectable } from ''@angular/core'';
import { Observable} from ''rxjs/Observable'';
@Injectable()
export class MyService {
private condition: Observable<boolean>;
constructor() {
this.condition= new Observable(ob => {ob.next(false); })
// maybe ob.next is not the best solution to assign the value?
}
change() {// how can i change the value of condition to ''true'', to call
// the doSomething function in the component??
}
}
Le sugiero que cambie su condición para ser un sujeto. El sujeto es tanto un observador como un observable. Entonces podrás emitir un valor.
Consulte https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md
Me gustaría explicar cómo usar los Observables en caso de que quiera actualizar el valor pero no usaré su ejemplo. Solo mostraré algunas líneas de código escritas en ES5 con explicaciones.
var updateObservable; // declare here in order to have access to future function
var observable = rx.Observable.create(function (observer) {
observer.next(1);
observer.next(2);
observer.next(3);
// attach a function to the variable which was created in the outer scope
// by doing this, you now have your ''updateObservable'' as a function and the reference to it as well
// You will be able to call this function when want to update the value
updateObservable = function (newValue) {
observer.next(newValue);
observer.complete();
};
});
// Suppose you want to update on click. Here actually can be whatever (event) you want
vm.click = function () {
// you can call this function because you have a reference to it
// and pass a new value to your observable
updateObservable(4);
};
// your subscription to changes
observable.subscribe(function(data) {
// after ''click'' event will be performed, subscribe will be fired
// and the ''4'' value will be printed
console.log(data);
});
La idea principal aquí es que si desea actualizar el valor de un Observable, debe hacer esto dentro de la función ''crear''. Esto será posible si declara una función dentro de esta función ''crear''.
Administrar el estado de inicio de sesión
Para esta implementación, solo necesitas un servicio. En él, haría su solicitud de back-end para ver si el usuario tiene una sesión, y luego puede guardarla en una variable de clase en el Servicio. Luego, devuelva esa variable si está configurada, o devuelva el resultado de una llamada REST directamente.
Por ejemplo:
export class AuthenticationService {
private loggedIn: boolean = null;
constructor(private http: Http) { }
getUserSession(credentials): Observable<boolean> {
if (this.loggedIn !== null) {
return Observable.of(this.loggedIn);
} else {
return this.http.get(''/authenticate?'' + credentials)
.map((session: Response) => session.json())
.catch(e => {
// If a server-side login gate returns an HTML page...
return Observable.of(false);
});
}
}
Y luego, en el Componente, simplemente suscríbase al Observable como de costumbre y actúe según lo solicite.
Hay otros métodos para lograr esto con Observable.share()
y Observable.replay()
Sintaxis observable
Para responder parte de la pregunta sobre la sintaxis de un Rx Observable en Angular2 (si alguien lo busca en Google), el formulario genérico es:
En un servicio:
return this.http.get("/people", null)
.map(res.json())
.catch(console.error("Error in service")
Y en un componente, a modo de ejemplo:
this.someService.getPeople()
.subscribe(
people => this.people,
error => console.warn(''Problem getting people: '' + error),
() => this.doneHandler();
);
Formalmente:
interface Observer<T> {
onNext(value: T) : void
onError(error: Error) : void
onCompleted() : void
}
La primera función se llama cuando se recibe el valor "siguiente". En el caso de llamadas REST (el caso más común) esto contiene el resultado completo.
La segunda función es un controlador de errores (en el caso en que se llamó a Observable.trow () en el servicio).
El último se llama cuando el conjunto de resultados tiene, y no toma parámetros. Aquí es donde puede llamar a su función doSomething ().