
Existing member? Log in and continue learning

See if you like it, start the course for free!

Unlock full course by purchasing a membership
Creating a Messages Service to Interact with Firestore
Creating a Messages Service to Interact with Firestore
Once again, our usual approach is to start with the “main” feature of the application. Although we will eventually have things like login and account creation, the main purpose of our application is creating and displaying messages. Let’s start there.
Create an Interface for messages
export interface Message { author: string; content: string; created: string;}
Creating the Message Service
import { Injectable, computed, inject, signal } from '@angular/core';import { Observable, merge } from 'rxjs';import { collection, query, orderBy, limit } from 'firebase/firestore';import { collectionData } from 'rxfire/firestore';import { map } from 'rxjs/operators';import { connect } from 'ngxtension/connect';
import { Message } from '../interfaces/message';import { FIRESTORE } from '../../app.config';
interface MessageState { messages: Message[]; error: string | null;}
@Injectable({ providedIn: 'root',})export class MessageService { private firestore = inject(FIRESTORE);
// sources messages$ = this.getMessages();
// state private state = signal<MessageState>({ messages: [], error: null, });
// selectors messages = computed(() => this.state().messages); error = computed(() => this.state().error);
constructor() { // reducers const nextState$ = merge( this.messages$.pipe(map((messages) => ({ messages }))) );
connect(this.state).with(nextState$); }
private getMessages() { const messagesCollection = query( collection(this.firestore, 'messages'), orderBy('created', 'desc'), limit(50) );
return collectionData(messagesCollection, { idField: 'id' }).pipe( map((messages) => [...messages].reverse()) ) as Observable<Message[]>; }}
Once again we have our basic state management setup, except this time we are
using the connect
function that we covered in the advanced state management
module.
To quickly recap, this is essentially the same idea as our normal reducers that we have been creating:
constructor() { // reducers const nextState$ = merge( this.messages$.pipe(map((messages) => ({ messages }))) );
connect(this.state).with(nextState$); }
Except rather than subscribing and calling state.update
with the source
values, instead we map
those values and return an object with whatever values
we want to set in the state. In this case, we return { messages }
because we
want to update the
Thanks for checking out the preview of this lesson!
You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).