Lotrèk
07 Dicembre 2017

Come creare una semplice To-do list con Angular 4 e Firebase


Pierdomenico  profile image
Human:
Pierdomenico 
Tempo
di lettura
40'

Angular 4 è forse il framework più utilizzato dagli sviluppatori web e mobile, in questo articolo vedremo come utilizzare l’integrazione con firebase per la creazione di una semplice webapp!

Vediamo come preparare il nostro ambiente per partire con i tool che abbiamo a disposizione.

Starter Kit

Per portare a termine tutorial ti serviranno pochi semplici tool.

Firebase CLI, fondamentale per procedere con il deploy. Puoi installarlo aprendo il terminale e digitando il comando:

> npm install -g firebase-tools

Angular CLI, per eseguire la struttura e l’impostazione del progetto

> npm install -g @angular/cli

Un editor di testo, io utilizzo Visual Studio Code

Impostiamo il nostro progetto Firebase

Prima di tutto vai sulla console di Firebase e crea un nuovo progetto

Clicca su Aggiungi Firebase all’applicazione web e copia il contenuto in un file di testo che ti servirà successivamente  

Vai nella sezione Database del menu e seleziona Prova Firestore in versione beta

Successivamente seleziona Avvia in modalità di prova

Nella schermata successiva Seleziona Aggiungi Raccolta

Successivamente aggiungi 2 campi con valori di default

Adesso il database è pronto per interagire con Angular!

Impostiamo il nostro progetto Angular

Prima di tutto genera il tuo progetto usando Angular CLI esegui il comando

> ng new todolist

Una volta completato il setup, spostati nella cartella todolist e installa i pacchetti necessari alla comunicazione con Firebase

> npm install angularfire2 firebase --save

Adesso puoi lanciare il comando che fa partire il browser

> ng serve

Il tuo progetto sarà raggiungibile all’indirizzo http://localhost:4200

Mettiamo le mani sul codice!

A questo punto apri il tuo editor di testo preferito e crea il file firebaseconfig.ts nella cartella /src/app.  i dati che hai salvato durante la fase di configurazione di Firebase.

//inserisci qui i dati che hai salvato in precedenza

export const firebaseConfig = {
 apiKey: '',
 authDomain: '',
 databaseURL: '',
 projectId: '',
 storageBucket: '',
 messagingSenderId: ''
};

Adesso vai a impostare il modulo app.module.ts che si trova nella stessa cartella

// sopra i moduli standard importati da angular
// moduli che occorrono per l'interazione con firebase
import { AngularFireModule } from 'angularfire2';
import { AngularFirestoreModule } from 'angularfire2/firestore';
// Credenziali di accesso a Firebase
import { firebaseConfig} from './firebaseconfig';
@NgModule({
 declarations: [
   AppComponent
 ],
 imports: [
   BrowserModule,
   FormsModule,
   HttpModule,
   AngularFireModule.initializeApp(firebaseConfig),
   AngularFirestoreModule
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }

Adesso metti le mani sul modulo app.component.ts per verificare se il collegamento al Firebase funziona come dovrebbe.

import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
interface Todos {
 description: string;
 done: boolean;
}
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
 todosCollection: AngularFirestoreCollection<todos>;
 todos: Observable<todos[]>;
 constructor(private afs: AngularFirestore) { }
 ngOnInit() {
   this.todosCollection = this.afs.collection('todos');
   this.todos = this.todosCollection.valueChanges();
 }
}

Prima di tutto definisci due proprietà:

todosCollection, del tipo Todos (l’interfaccia che abbiamo definito sopra).

todos che contiene l’array che ci viene ritornato.

Nella funzione ngOnInit, eseguita al caricamento del componente, fai un bind di todosCollection all’istanza di AngularFirestore, usando il metodo .collection al quale dovrai passare il nome della raccolta (todos)

Successivamente fai un bind di todos a todosCollection e usa il metodo .valuechanges() che ti ritornerà un “observable”.

Adesso nel modulo app.component.html fai apparire i contenuti presi da Firebase.

<ul>
 <li *ngfor="let todo of todos | async">
   <b>{{todo.description}}</b>
   <em>{{todo.done}}</em>
 </li>
</ul>

Adesso è arrivato il momento di aggiungere i to-do.

Sempre in app.component.html aggiungi il markup del tuo form

<form>
 <input type="text" [(ngmodel)]="description" name="description" placeholder="Cosa devo fare ...">
 <button type="submit" (click)="addTodo()"> Aggiungi Todo</button>
</form>

In app.component.ts , crea la proprietà description, che ti servirà per fare il 2-way data binding al [(ngModel)]

description: string;

all’interno della classe AppComponent aggiungi la funzione addTodo()

addTodo() {
   this.afs.collection('todos').add({
     'description': this.description,
     'done': false
   });
 }

Ovviamente passeremo alla funzione il valore di ngModel, mentre per quanto riguarda il parametro ‘done’ bisognerà passare false di default

Spuntiamo  i nostri to-do

È arrivato il momento di spuntare i to-do. Per fare ciò avremo bisogno di poter selezionare un singolo todo dal database.

Purtroppo, allo stato attuale, utilizzando .valueChanges(), non hai la possibilità di ottenere l’id di ogni singolo to-do, perché è considerato un metadata.

Per ottenere questo risultato bisognerà apportare un po’ di modifiche al nostro codice.

Prima di tutto, esattamente sotto l’interfaccia Todos, ne aggiungiamo una nuova che estende quest’ultima.

interface Todo extends Todos {
 id: string;
}

Successivamente modifica la proprietà todos

todos: Observable<todos[]>;

A questo punto bisogna ridefinire this.todos all’.ngOnInit() per poter usare .snapshotChanges(), che differentemente dal precedente metodo restituisce anche diversi metadata che includono l’id del todo.

this.todos = this.todosCollection.snapshotChanges()
     .map(actions => {
       return actions.map(a => {
         const data = a.payload.doc.data() as Todo;
         const id = a.payload.doc.id;
         return { id, data };
       });
     });

Bisognerà modificare anche il tuo template.

<ul>
 <li *ngfor="let todo of todos | async">
   <i>{{todo.id}}</i>
   <b>{{todo.data.description}}</b>
   <em>{{todo.data.done}}</em>
 </li>
</ul>

Adesso scrivi la funzione che permetterà di aggiornare i todo.

Modifica il tuo template per ottenere il risultato desiderato.

<ul>
 <li *ngfor="let todo of todos | async">
   <input [checked]="todo.data.done" type="checkbox" (change)="updateTodo(todo.id, $event)">
   <b [class.done]="todo.data.done">{{todo.data.description}}</b>
 </li>
</ul>

Aggiungi una checkbox che ti permetterà di segnare un’attività come completata oppure no. Imposta “checked” se il valore di todo.data.done è uguale a true, al change esegui invece la funzione updateTodo(), passando l’id e l’evento scatenato al change. Infine imposta una classe done, se todo.data.done è true.

Nello styles.css inserisci

.done{
 text-decoration: line-through;
}

Nel component invece definisci updateTodo()

updateTodo(id, event) {
   const checkedVal = event.target.checked;
   this.afs.doc('todos/' + id).update({
     'done': checkedVal
   });
 }

Come puoi vedere non facciamo altro che utilizzare il medodo .doc(), che ci permette di selezionare un singolo todo tramite l’id. Fatto questo utilizziamo il metodo .update() per aggiornarlo.

Eliminare un todo

Utilizzeremo più o meno la stessa tecnica adottata prima per impostare la funzionalità di update.

Nel template, all’interno del ciclo for, aggiungi il bottone che permetterà di cancellare i tuoito-do.

<button *ngif="todo.data.done" (click)="removeTodo(todo.id)">×</button>

Mostra il bottone esclusivamente se il to-do è checkato, e ovviamente passiamo alla funzione l’id.

removeTodo(id){
   this.afs.doc('todos/' + id).delete();
 }

Differentemente da prima, utilizzeremo il metodo .delete(), i nostri to-do verranno cancellati dalla lista.

Aggiungiamo un po’ di stile alla nostra app!

Nel template aggiungi un header

<header>
   <h1>...
</h1></header>

e un main

<main>
 <ul>
    ....
 </ul>
</main>

Nel file styles.css aggiungi

body{
 font-family: 'Helvetica Neue', sans-serif;
 background: #ededed;
 margin: 0;
}
header{
 background: #ff6666;
 padding:.5em;
 display: flex;
 align-items: center;
}
header img{
 max-height: 2em;
}
h1{
 font-weight: 100;
 color: white;
 margin: 0 .5em 0 0;
}
main {
   max-width: 800px;
   margin: 0 auto;
   display: block;
   padding: 2em 1em;
}
textarea, input, button { outline: none; }
form{
 display:flex;
 width: 100%;
 align-items: center;
 box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.15);
}
form input{
 flex:1;
}
form button{
 background:#1c1c1c;
}
form button:hover{
 background:#ff6666;
}
ul {
   list-style: none;
   padding: 0;
}
li {
   background: white;
   margin: .5em 0;
   padding: .5em;
   align-items: center;
   display: flex;
   box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.15);
}
li b{
 font-weight: 100;
 font-size: 1.5em;
 margin: 0 .5em;
 flex:1;
 transition: all .3s;
}
button {
   font-weight: 300;
   color: #ff6666;
   border: none;
   border-radius: 0;
   background: white;
   padding: 1em;
   font-size: .8em;
   cursor: pointer;
   transition: all .3s;
   box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.15);
}
button:hover{
    background: #ededed;
}
input[type="text"] {
   background: none;
   border: none;
   background:white;
   font-size: 1.5em;
   padding: .25em;
   font-weight: 100;
   transition: all .3s;
}
input[type="text"]:focus{
 color: #ff6666;
}
.done{
 text-decoration: line-through;
}

Ecco come apparirà la tua app

È tempo di deploy!

Deployare un’app sfruttando l’hosting che ci offre Firebase è molto semplice, bastano pochi semplici passi.

Prima di tutto vai alla sezione Hosting all’interno della nostra console di Firebase e clicca su inizia

Firebase ti suggerisce di installare la sua CLI, se non lo hai fatto in precedenza, installala adesso e clicca su continua.

Nel secondo passaggio ti vengono fornite tutte le istruzioni per poter procedere con il deploy

Quando lanci il comando firebase init, se non conosci molto bene come funzionano le configurazioni di Firebase, Ti consiglio di selezionare solo l’opzione hosting, per evitare di confonderti con tutte le configurazioni che Firebase mette a disposizione.

Et voilà… la tua app sarà online in pochi minuti!

L’intero codice del tutorial è disponibile su github:

https://github.com/lotrekagency/Todolistfirebase

In questo tutorial abbiamo visto quanto sia facile ed intuitivo sviluppare una semplice web app con degli strumenti potentissimi quali Angular e Firebase. Pensa a quanto potrebbe tornare comodo avere una piattaforma che ti permette di gestire il back-end delle tue app in maniera veloce e con una curva di apprendimento estremamente bassa.

Vi aspetto per nuovi fantastici Tutorial!



Condividi

Ho iniziato ad approcciarmi con il mondo del web non appena finite le scuole superiori, una mia amica mi disse che frequentava una scuola di web design, così senza pensarci troppo mi iscrissi e fu amore a prima vista. Ho iniziato ad avvicinarmi alla progettazione e alla grafica, ma mi sentivo incompleto, volevo far funzionare quello che disegnavo, e allora è arrivato il mio secondo amore, lo sviluppo Front end. Dopo un esperienza in una grande realtà del digital, ho deciso che le Big Company non facevano per me, avevo bisogno di nuovi stimoli continui, e fu così che incotrai Lotrèk. Continuando ad andare avanti mi sono sentito trascinare sempre più in profondità nello sviluppo, e cosi ho iniziato ad interessarmi allo sviluppo Back end. Però non vi preoccupate, la mia vita non è solo fatta di righe di codice, suono il basso in una band e pratico MMA

 Invio email in corso, yeah!
Richiesta inviata
C'è stato un problema riprova più tardi