Two attributes do not persist in a JSON

1

I'm doing a project with Angular 6 and Cloud Firestore, which consists of adding products. I have defined an interface with the attributes that must be carried, and when I receive them from a form, I manage them with the service:

addProduct(idDepartament: string, product: Product, image: File) {
    const id = this.db.createId();
    const document = this.db.doc('departaments/${idDepartament}/products/${id}');
    // Aquí sí presiste el ID del producto
    product.id = id;

    if (image) {
      // Si existe la imagen, entonces la guardará en Firebase Storage
      const path = 'images/${idDepartament}/${id}/${image.name}';
      const ref = this.storage.ref(path);
      const task = this.storage.upload(path, image);
      task.snapshotChanges().pipe(
        finalize(() => {
          ref.getDownloadURL().subscribe((data: string) => {
            product.image = data; // Guarda la dirección donde se almacenó la imagen
            product.nameImage = image.name; // Guarda el nombre de la imagen
          });
        })).subscribe();
    } else {
      // Si no hay imagen, tendrá una por defecto
      product.image = './assets/img/noImage.png';
    }

    // Retorna una promesa para mostrar si todo salió bien, o hubo un problema en la subida del archivo
    return document.set(product);
  }

I think everything is fine, however, when testing it does not save nameImage or image in product . And I verified that if they appear in the object: Objecto product

What happens? It seems that he is saving it correctly. However, the two attributes for the image are not found in the Database: Archive in Firebase

Thanks. I hope you can clarify this strange event, because a couple of days ago it worked well, and now you do not want to store those two attributes.

    
asked by Franco Salvador Hernndez Hernn 13.08.2018 в 11:24
source

1 answer

0

The problem is that you are doing asynchronous jobs and when you do document.set(product) the image has not yet been saved in the database.

You need to wait for the image to be saved completely, so that the code in which image and nameImage are saved will be executed and then (and only then) you will have everything ready to save.

One possible solution (of many) would be the following:

addProduct(idDepartament: string, product: Product, image: File) {
   const id = this.db.createId();
   const document = this.db.doc('departaments/${idDepartament}/products/${id}');
   product.id = id;

  // Preparamos una Promesa para cuando se termine el trabajo con la imagen
  const p = new Promise<Product>((resolve, reject) => {
     if (image) {
        // Si existe la imagen, entonces la guardará en Firebase Storage
        const path = 'images/${idDepartament}/${id}/${image.name}';
        const ref = this.storage.ref(path);
        const task = this.storage.upload(path, image);
        task.snapshotChanges().pipe(
          // finalize no se ejecutará sino hasta que se guarde la imagen
          finalize(() => {
            ref.getDownloadURL().subscribe((data: string) => {
              product.image = data; 
              product.nameImage = image.name; 
              // Resolver la promesa con el producto actualizado
              resolve(product);
            });
          })).subscribe();
      } else {
        // Si no hay imagen, tendrá una por defecto
        product.image = './assets/img/noImage.png';
        // Resolver la promesa con el producto actualizado
        resolve(product);
      }
   });

   // Esperamos que se resuelva la promesa anterior
   return p.then((resultProduct) => {
      // Retorna una promesa para mostrar si todo salió bien, o hubo un problema en la subida del archivo
      return document.set(resultProduct);
   });
}
    
answered by 14.08.2018 в 08:16