admin管理员组文章数量:1397175
Explanation of Observable Post
setupponent.ts
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Post } from './model/post';
import { PostService } from './service/post.service';
@Component({
selector: 'setup',
templateUrl: './setupponent.html',
styleUrls: ['./setupponent.scss']
})
export class SetupComponent implements OnInit {
@Output()
change: EventEmitter<string> = new EventEmitter();
postUsers(input){
this.postService.postUser(input)
.subscribe(
post => {
this.post = post
},
err => {
console.log(err);
});
}
clicked(value) {
console.log(value);
this.postUsers(this.input)
// this.change.emit(value);
}
plexForm : FormGroup;
constructor(private postService: PostService) {}
post: Post[];
ngOnInit() {}
}
post.service.ts
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Post } from '../model/post';
import { Observable } from 'rxjs/Rx';
// Import RxJs required methods
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class PostService {
constructor (private http: Http) {}
private registerUrl = 'http://localhost:2001/api/users/register';
postUser(user:Post) : Observable<Post[]>{
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.registerUrl, user, options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
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);
}
}
model/post.ts
export class Post {
constructor(
public id: number,
public name: string,
public email: string,
public password: string
){}
}
I understand what the model/post.ts does, it defines the property types, what I need is clarification on the subscribe method within setupponents.ts
. The Observable gets invoked inside clicked()
but what I want to understand is how does this because accessible to the application so that I can proceed after the action has run its course this.postUsers(this.input)
Typically with a Promise I would have done the following
this.postUsers(this.input)
.then(function(){
});
I'd really like it if someone could explain how it works and how to achieve a confirmation that the post has pleted to then run the next function
ie I have this
clicked(value) {
console.log(value);
this.postUsers(this.input)
// this.change.emit(value);
}
but in promise I'd do
clicked(value) {
console.log(value);
this.postUsers(this.input)
.then(function(){
this.change.emit(value);
});
}
How can I get this to work with Observables? I tried to see what was returned by doing
clicked(value) {
console.log(value);
const runThis = this.postUsers(this.input);
console.log(runThis);
// this.change.emit(value);
}
but it returns undefined
.
Explanation of Observable Post
setup.ponent.ts
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Post } from './model/post';
import { PostService } from './service/post.service';
@Component({
selector: 'setup',
templateUrl: './setup.ponent.html',
styleUrls: ['./setup.ponent.scss']
})
export class SetupComponent implements OnInit {
@Output()
change: EventEmitter<string> = new EventEmitter();
postUsers(input){
this.postService.postUser(input)
.subscribe(
post => {
this.post = post
},
err => {
console.log(err);
});
}
clicked(value) {
console.log(value);
this.postUsers(this.input)
// this.change.emit(value);
}
plexForm : FormGroup;
constructor(private postService: PostService) {}
post: Post[];
ngOnInit() {}
}
post.service.ts
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Post } from '../model/post';
import { Observable } from 'rxjs/Rx';
// Import RxJs required methods
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class PostService {
constructor (private http: Http) {}
private registerUrl = 'http://localhost:2001/api/users/register';
postUser(user:Post) : Observable<Post[]>{
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.registerUrl, user, options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
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);
}
}
model/post.ts
export class Post {
constructor(
public id: number,
public name: string,
public email: string,
public password: string
){}
}
I understand what the model/post.ts does, it defines the property types, what I need is clarification on the subscribe method within setup.ponents.ts
. The Observable gets invoked inside clicked()
but what I want to understand is how does this because accessible to the application so that I can proceed after the action has run its course this.postUsers(this.input)
Typically with a Promise I would have done the following
this.postUsers(this.input)
.then(function(){
});
I'd really like it if someone could explain how it works and how to achieve a confirmation that the post has pleted to then run the next function
ie I have this
clicked(value) {
console.log(value);
this.postUsers(this.input)
// this.change.emit(value);
}
but in promise I'd do
clicked(value) {
console.log(value);
this.postUsers(this.input)
.then(function(){
this.change.emit(value);
});
}
How can I get this to work with Observables? I tried to see what was returned by doing
clicked(value) {
console.log(value);
const runThis = this.postUsers(this.input);
console.log(runThis);
// this.change.emit(value);
}
but it returns undefined
.
- is there still anything unclear in my answer? – Max Koretskyi Commented Jul 17, 2017 at 17:59
2 Answers
Reset to default 4Similar with promises make your postUsers
method return an observable (not a subscription)
postUsers(input){
return this.postService.postUser(input);
}
Then you can subscribe to this method like using a then
in promises.
clicked(value) {
console.log(value);
this.postUsers(this.input).subscribe((response)=> {
this.change.emit(value);
});
}
You can also convert observables into promises. Then you wouldn't get confused.
import 'rxjs/add/operator/toPromise';
postUsers(input){
return this.postService.postUser(input).toPromise();
}
clicked(value) {
console.log(value);
this.postUsers(this.input)
.then((res)=>{
this.change.emit(value);
});
}
Note that I haven't used the function
keyword in my callbacks. If I did this.change
would refer to the callbacks change
because the this
wouldn't refer to the ponent.
how to achieve a confirmation that the post has pleted
When the stream triggers plete
callback you will know the request has pleted. This is the third callback you pass to the subscribe method or the plete
method if you pass observer object instead of callbacks.
I think you will benefit from knowing how the operator toPromise
work. You can then use it directly or emulate its logic. You can use it:
this.postUsers(this.input).toPromise()
.then(function(){
...
});
Basically what it does is creates a promise and returns it. Then it subscribes the the observable returned by the this.postUsers
and waits until this observable emits pleted
event. After that, it resolves the promise with the last event it returned. Something along these lines:
toPromise(observable) {
let lastReturnedValue = null;
return new Promise() {
observable.subscribe(
(v)=>{
lastReturnedValue = v;
},
(e)=>{
reject(e);
},
(c)=>{
resolve(lastReturnedValue);
});
}
}
So just as with toPromise
you can subscribe to the observable and listen for plete
event:
clicked(value) {
console.log(value);
this.postUsers(this.input).subscribe(
(v)=>{ // here you get the value and can save it },
(e)=>{ // here you know that observable has error, similar to `catch` callback },
()=>{ // here you know that observable has pleted, similar to `then` callback}
);
console.log(runThis);
// this.change.emit(value);
}
Or you can return the observable for someone else to listen:
clicked(value) {
return this.postUsers(this.input)
}
...
clicked().subscribe( // all the code from previous example)
本文标签: javascriptAngular observable post and subscribe explanationHow it worksStack Overflow
版权声明:本文标题:javascript - Angular observable post and subscribe explanationHow it works - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744124724a2591903.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论