Search code examples
angulardatabaseservicesubject

In angular, how to add element to the view and db, then delete it directly after without knowing the id?


Here is my problem. I have a list of folder like that :

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Subscription } from 'rxjs';
import { Folder } from '../models/folder.model';
import { FoldersService } from '../services/folders.service';

@Component({
  selector: 'app-folders-list',
  templateUrl: './folders-list.component.html',
  styleUrls: ['./folders-list.component.scss']
})
export class FoldersListComponent implements OnInit {

  folders: Folder[];
  folderSubscription: Subscription;

  constructor(private foldersService: FoldersService) { }

  ngOnInit(): void {
    this.folderSubscription = this.foldersService.folderSubject.subscribe(
      (folders: Folder[]) => {
        this.folders = folders;
      }
    );
    this.foldersService.emitFolderSubject();
  }

  ngOnDestroy() {
    this.folderSubscription.unsubscribe();
  }

  onSubmit(form: NgForm) {
    const title = form.value['title'];
    const newFolder = new Folder(title);
    this.foldersService.createNewFolder(newFolder);
  }

}

All data are managed by the FolderService below. Only him interact with the database. When I post, get or delete element from the database, the service does it. My problem is the following one: When I create an element, the database herself manages the id, I mean the database choose an id by autoincrement. But to directly delete it after, I need this id ! I only found two solutions that seem weird to me:

  • Reupdate the view by doing an other "getFolders" request. But if the list is huge, I would have to make a huge get request after each post request...

  • Choose an ID in the app, but it would change my whole app logic... Any ideas ?

      import { Injectable } from '@angular/core';
      import { Subject } from 'rxjs';
      import { environment } from 'src/environments/environment';
      import { Folder } from '../models/folder.model';
      import { HttpClient } from '@angular/common/http';
    
    
      @Injectable({
        providedIn: 'root'
      })
      export class FoldersService {
    
        private folders: Folder[] = [];
        folderSubject = new Subject<Folder[]>();
    
        private url:string = environment.BACKEND_HTTPS_SERVER;
        private endpoint:string = "/folders";
    
        constructor(private http: HttpClient) {
          this.getFolders();
        }
    
        emitFolderSubject() {
          this.folderSubject.next(this.folders.slice());
        }
    
        getFolders() {
          this.http
            .get<any>(this.url+this.endpoint)
            .subscribe(
              (response) => {
                this.folders = response;
                this.emitFolderSubject()
              },
              (error) => {
                console.log('Error : ' + error);
              }
            )
        }
    
        createNewFolder(newFolder: Folder) {
          //this.folders.push(newFolder);
          this.http
            .post(this.url+this.endpoint, {
              "title": newFolder.title
            })
            .subscribe(
              (_) => {
                console.log("Successfully added.");
                this.getFolders();
              },
              (error) => {
                console.log("Error : ", error);
              }
            )
        }
    
        deleteFolder(id: number) {
          const elementPos = this.folders.map(function(o) { return o.folderId;}).indexOf(id);
          this.folders.splice(elementPos,1);
          this.http
            .delete(this.url+this.endpoint+"/"+id)
            .subscribe(
              (_) => {
                console.log("Successfully deleted.");
                this.emitFolderSubject();
              },
              (error) => {
                console.log("Error : ", error);
              }
            )
        }
    

    }


Solution

  • Depending on how your backend is configured, the http.post often returns the new saved object with the id as set by the backend server. So you can access it in your subscribe, something like this:

    .subscribe(
              folder => {
                console.log("Successfully added folder: " + folder.id);
              },
              (error) => {
                console.log("Error : ", error);
              }
            )
    

    Does that help?