将字符串推送到 observable<chatmessages[ ]>
push string to observable<chatmessages[ ]>
我正在尝试创建一个聊天应用程序,并希望用户发送的消息显示在聊天室中(在我的项目中称为提要),就像显示所有其他已经存在的消息一样 (我有一个getMessages()
)
如何将用户键入的消息推送到我的 chatMessage[]
?
这是我的message.Service.ts
@Injectable({
providedIn: 'root'
})
export class MessageService {
user: User;
userName: Observable<string>;
chatMessage: ChatMessage;
chatMessages$: Observable<ChatMessage[]>;
constructor(
private http: HttpClient,
private accountService: AccountService) {
this.user = this.accountService.userValue;
}
sendMessage(msg: string){
const timestamp = this.getTimeStamp()
this.chatMessages$ = this.getMessages();
this.chatMessages$.push({ //having trouble here
msg_content: msg, //Property 'push' does not exist on type 'Observable<ChatMessage[]>'.
timeSent: timestamp,
userName: this.userName,
email: this.user.email });
var formdata = new FormData();
formdata.append("sender_email", this.user.email);
formdata.append("sender_key", this.user.api_key);
formdata.append("msg_content", msg);
this.http.post("http://11.123.456.78:5000/messages/send_message", formdata )
.subscribe(response => console.log(response), error => console.log('oops', error));
}
getMessages(){
let params = new HttpParams().set("sender_email", "this.user.email").set("sender_key", "someapikey"); //Create new HttpParams
var url = "http://11.123.456.78:5000/messages/get_all_messages";
return this.chatMessages$ = this.http.get<ChatMessage[]>(url, { params: params});
}
}
我的feed.component.ts
export class FeedComponent implements OnInit {
chatMessages$: Observable<ChatMessage[]>;
messages;
messageObjects: string[] = [];
constructor(private chat: MessageService) {
}
ngOnInit() {
this.messages = this.chat.getMessages().subscribe((allmessagesdata => { this.messages = allmessagesdata
for (let messageObject of this.messages){
this.messageObjects.push(messageObject.msg_content)
};
}));
this.chatMessages$ = this.chat.getMessages();
}
ngOnchanges(){
this.chat.getMessages().subscribe((allmessagesdata => { this.messages = allmessagesdata, console.log(this.messages)}))
}
}
我的feed.html
<div *ngFor="let message of ( chatMessages$ | async )" >
<app-message [chatMessage]="message"> </app-message>
</div>
我的聊天-message.model.ts
export class ChatMessage {
$id?: string;
email?: string;
userName?: string;
msg_content?: string;
timeSent?: Date = new Date();
}
这是我已经尝试过的方法:
我尝试设置 private subject = new Subject<string>();
然后在我的 sendMessage() 函数中说 this.subject.next(msg)
然后我创建了
getMessage():Observable<string> {
return this.subject.asObservable();
}
并在我的供稿中订阅了它,但这只允许一个消息值。
我对可观察对象和主题的了解有限,我似乎还不能完全掌握这个概念,但我知道我必须为此目的使用它们,因此非常感谢任何帮助
您不能将某些内容推送到可观察对象,因为它是一个流。您所描述的可以通过许多不同的方法来完成。例如,您可以创建 ChatMessage[] 的 BehaviorSubject,它将存储“最近”消息,然后 chatMessages$ 应该是后端消息和最近消息的组合。
我的提议(我想到的第一个,在这里操场上做了一些概念测试:https://stackblitz.com/edit/rxjs-evjqhb)
@Injectable({
providedIn: 'root'
})
export class MessageService implements OnInit, OnDestroy{
user: User;
userName: Observable<string>;
private _sendMessage = new Subject<ChatMessage>();
private _destroy = new Subject<ChatMessage>();
private _recentMessages = new BehaviorSubject<ChatMessage[]>([]);
chatMessage: ChatMessage;
existedChatMessages$: Observable<ChatMessage[]>;
recentChatMessages$: Observable<ChatMessage[]>;
chatMessages$: Observable<ChatMessage[]>;
constructor(
private http: HttpClient,
private accountService: AccountService) {
this.user = this.accountService.userValue;
}
sendMessage(msg: string){
const timestamp = this.getTimeStamp()
const message = {
msg_content: msg,
timeSent: timestamp,
userName: this.userName,
email: this.user.email };
this._sendMessage.next(message);
// you can move this to a tap() operator in the _sendMessage subject
var formdata = new FormData();
formdata.append("sender_email", this.user.email);
formdata.append("sender_key", this.user.api_key);
formdata.append("msg_content", msg);
this.http.post("http://11.123.456.78:5000/messages/send_message", formdata )
.subscribe(response => console.log(response), error => console.log('oops', error));
}
getMessages(){
let params = new HttpParams().set("sender_email", "this.user.email").set("sender_key", "someapikey"); //Create new HttpParams
var url = "http://11.123.456.78:5000/messages/get_all_messages";
return this.chatMessages$ = this.http.get<ChatMessage[]>(url, { params: params});
}
ngOnInit(){
chatMessages$ = this.existedChatMessages$.pipe(
switchMap(existed=>
this.recentChatMessages$].pipe(
map(recent)=>[...(existed||[]), ...recent]
)
)
); // combine streams of backend & recent messages
this.existedChatMessages$ = this.getMessages();
this.recentChatMessages$ = this._recentMessages.asObservable();
this._recentMessages.pipe(
switchMap(recentMessages => this._sendMessage.pipe(
map(message=> [...recentMessages, message]))
)
),
tap(x=> this._recentMessages.next(x)),
takeUntil(this._destroy)
).subscribe(); // creating subscription for sendMessage subject to update recentMessages collection
}
ngOnDestroy(){
this._destroy.next();
this._destroy.complete();
}
}
我正在尝试创建一个聊天应用程序,并希望用户发送的消息显示在聊天室中(在我的项目中称为提要),就像显示所有其他已经存在的消息一样 (我有一个getMessages()
)
如何将用户键入的消息推送到我的 chatMessage[]
?
这是我的message.Service.ts
@Injectable({
providedIn: 'root'
})
export class MessageService {
user: User;
userName: Observable<string>;
chatMessage: ChatMessage;
chatMessages$: Observable<ChatMessage[]>;
constructor(
private http: HttpClient,
private accountService: AccountService) {
this.user = this.accountService.userValue;
}
sendMessage(msg: string){
const timestamp = this.getTimeStamp()
this.chatMessages$ = this.getMessages();
this.chatMessages$.push({ //having trouble here
msg_content: msg, //Property 'push' does not exist on type 'Observable<ChatMessage[]>'.
timeSent: timestamp,
userName: this.userName,
email: this.user.email });
var formdata = new FormData();
formdata.append("sender_email", this.user.email);
formdata.append("sender_key", this.user.api_key);
formdata.append("msg_content", msg);
this.http.post("http://11.123.456.78:5000/messages/send_message", formdata )
.subscribe(response => console.log(response), error => console.log('oops', error));
}
getMessages(){
let params = new HttpParams().set("sender_email", "this.user.email").set("sender_key", "someapikey"); //Create new HttpParams
var url = "http://11.123.456.78:5000/messages/get_all_messages";
return this.chatMessages$ = this.http.get<ChatMessage[]>(url, { params: params});
}
}
我的feed.component.ts
export class FeedComponent implements OnInit {
chatMessages$: Observable<ChatMessage[]>;
messages;
messageObjects: string[] = [];
constructor(private chat: MessageService) {
}
ngOnInit() {
this.messages = this.chat.getMessages().subscribe((allmessagesdata => { this.messages = allmessagesdata
for (let messageObject of this.messages){
this.messageObjects.push(messageObject.msg_content)
};
}));
this.chatMessages$ = this.chat.getMessages();
}
ngOnchanges(){
this.chat.getMessages().subscribe((allmessagesdata => { this.messages = allmessagesdata, console.log(this.messages)}))
}
}
我的feed.html
<div *ngFor="let message of ( chatMessages$ | async )" >
<app-message [chatMessage]="message"> </app-message>
</div>
我的聊天-message.model.ts
export class ChatMessage {
$id?: string;
email?: string;
userName?: string;
msg_content?: string;
timeSent?: Date = new Date();
}
这是我已经尝试过的方法:
我尝试设置 private subject = new Subject<string>();
然后在我的 sendMessage() 函数中说 this.subject.next(msg)
然后我创建了
getMessage():Observable<string> {
return this.subject.asObservable();
}
并在我的供稿中订阅了它,但这只允许一个消息值。
我对可观察对象和主题的了解有限,我似乎还不能完全掌握这个概念,但我知道我必须为此目的使用它们,因此非常感谢任何帮助
您不能将某些内容推送到可观察对象,因为它是一个流。您所描述的可以通过许多不同的方法来完成。例如,您可以创建 ChatMessage[] 的 BehaviorSubject,它将存储“最近”消息,然后 chatMessages$ 应该是后端消息和最近消息的组合。
我的提议(我想到的第一个,在这里操场上做了一些概念测试:https://stackblitz.com/edit/rxjs-evjqhb)
@Injectable({
providedIn: 'root'
})
export class MessageService implements OnInit, OnDestroy{
user: User;
userName: Observable<string>;
private _sendMessage = new Subject<ChatMessage>();
private _destroy = new Subject<ChatMessage>();
private _recentMessages = new BehaviorSubject<ChatMessage[]>([]);
chatMessage: ChatMessage;
existedChatMessages$: Observable<ChatMessage[]>;
recentChatMessages$: Observable<ChatMessage[]>;
chatMessages$: Observable<ChatMessage[]>;
constructor(
private http: HttpClient,
private accountService: AccountService) {
this.user = this.accountService.userValue;
}
sendMessage(msg: string){
const timestamp = this.getTimeStamp()
const message = {
msg_content: msg,
timeSent: timestamp,
userName: this.userName,
email: this.user.email };
this._sendMessage.next(message);
// you can move this to a tap() operator in the _sendMessage subject
var formdata = new FormData();
formdata.append("sender_email", this.user.email);
formdata.append("sender_key", this.user.api_key);
formdata.append("msg_content", msg);
this.http.post("http://11.123.456.78:5000/messages/send_message", formdata )
.subscribe(response => console.log(response), error => console.log('oops', error));
}
getMessages(){
let params = new HttpParams().set("sender_email", "this.user.email").set("sender_key", "someapikey"); //Create new HttpParams
var url = "http://11.123.456.78:5000/messages/get_all_messages";
return this.chatMessages$ = this.http.get<ChatMessage[]>(url, { params: params});
}
ngOnInit(){
chatMessages$ = this.existedChatMessages$.pipe(
switchMap(existed=>
this.recentChatMessages$].pipe(
map(recent)=>[...(existed||[]), ...recent]
)
)
); // combine streams of backend & recent messages
this.existedChatMessages$ = this.getMessages();
this.recentChatMessages$ = this._recentMessages.asObservable();
this._recentMessages.pipe(
switchMap(recentMessages => this._sendMessage.pipe(
map(message=> [...recentMessages, message]))
)
),
tap(x=> this._recentMessages.next(x)),
takeUntil(this._destroy)
).subscribe(); // creating subscription for sendMessage subject to update recentMessages collection
}
ngOnDestroy(){
this._destroy.next();
this._destroy.complete();
}
}