I saw similarly asked questions but I am having a hard time applying it to my code.
I have the following piece of code:
  createSubmission(sub: Submission, files: Files[]): Promise {
    //first add files to storage and create the url array
    let urlArray: string[];
    return files.forEach(file => {
      var storageRef = this.storage.ref(`files/${file.name}`);
      return storageRef.put(file).then(()=> {storageRef.getDownloadURL().subscribe(url => {
        urlArray.push(url);
        if(urlArray.length === files.length){ //we are at the final element
          sub.filesUrls = urlArray;
          return this.finilize(sub);
        }
      })
    });
    });
  }
  finilize(sub: Submission){ //actually creates the submission
    
      let subRef = this.db.database.ref(`/submissions/${sub.medicUid}`).push(); 
      let subKey = subRef.getKey();
      sub.uid = subKey; 
      return subRef.update(sub);
  }
The caller of the first method (createSubmission) should receive a Promise. My code sequence is finilized when we return from the finilize method.
I want to continue after all the elements in the loop have been iterated, and the urlArray has been filled. It is filled when it has the same number of elements as the passed files array, that's why I placed this condition:
if(urlArray.length === files.length){...}
However, I get an error because the if condition means that Not all code paths return a value.  So I believe I should ditch the if condition and wait for all promises to resolve before calling finalize, but I am not very clear on how to do it.
 
     
     
     
    