0

I need to send some information to an API using JSON. Among this information will be a base64 array, but that array is getting empty.

In my code I have an array of files with images:

[0: File {name: '766_generated.jpg', lastModified: 1613057822000, lastModifiedDate: Thu Feb 11 2021 12:37:02 GMT-0300 (Horário Padrão de Brasília), webkitRelativePath: '', size: 191010, …}]

In my function I make a map in the image array, transform it into base64 and put it in another array:

let filesBody = []
this.files.map(item => {
        var reader = new FileReader();
        reader.readAsDataURL(item);
        reader.onload = function () {
          let result = reader.result
          return filesBody.push(result)
        };
      })

console.log(filesBody):

[0: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD…AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/Z"]

body:

let body = { "files": filesBody }

console.log(body):

{
    "files": ['data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD…AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/Z']
}

POST:

this.billingService.sendBillingRevaluation(body)

service:

sendBillingRevaluation(body): Observable<any> {
    return this.http.post<any>(
      `${ServicesUrls.URL}/queries/sendBillingRevaluation`,
      body
    )
  }

After doing this to get the base64 array I send the body by POST but the base64 array is being sent empty:

{
    "files": []
}

To identify that it was being sent empty, I used two ways: network tab in browser and endpoint log in backend

Is there any different way to send base64 to JSON?

Leticia Fatima
  • 512
  • 2
  • 4
  • 19
  • Can you clarify how you know it's being sent empty? Are you seeing this in the network tab of web dev tools? Or does the web request look fine and the API isn't receiving the data? Can you update your question to show how you are executing the API request? On a side not, `Array.prototype.map` is probably not the best method to use in your case as `map` returns a new array, `forEach` may be a better option as you aren't using the output of `map`. – Alexander Staroselsky Nov 03 '21 at 14:29
  • To identify that it was being sent empty, I used two ways: network tab in browser and endpoint log in backend – Leticia Fatima Nov 03 '21 at 14:31
  • Update your question to show how you are sending the request and how it uses `filesBody`. – Alexander Staroselsky Nov 03 '21 at 14:32
  • 1
    You should look at [Convert array of inputted files to base64 using FileReader](https://stackoverflow.com/q/63491367/215552) – Heretic Monkey Nov 03 '21 at 14:38
  • Remove `return` from `return filesBody.push(result)`. `push` returns the new length of the `filesBody` array after pushing `result` into it. Returning that to the `onload` handler does nothing good. Also, remember that is an asynchronous process. Your `map` function will complete and `filesBody` will be empty because the `files` will not have been read yet. That's why it's empty when you post. – Heretic Monkey Nov 03 '21 at 14:45
  • Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Heretic Monkey Nov 03 '21 at 14:46
  • They aren't using the return of `map` so that wouldn't be the cause. My question is where exactly `let body = { "files": filesBody }` is defined? That doesn't look like a class property and it's not present in `sendBillingRevaluation`. Where/when is that being defined and when is the `map` executed? It's not clear that `filesBody`/`body` is effectively set at the time `sendBillingRevaluation` is executed. – Alexander Staroselsky Nov 03 '21 at 14:58
  • @AlexanderStaroselsky is in the same order as I put in the question, I create the body, give the body a console.log and post it. In console.log it has base64 inside "files" – Leticia Fatima Nov 03 '21 at 15:04
  • Can you try creating a simple example of your app using something like https://stackblitz.com/ for further troubleshooting? – Alexander Staroselsky Nov 03 '21 at 15:27

1 Answers1

0

I got the solution based on the question: Convert array of inputted files to base64 using FileReader

My final code:

Promise.all(
        this.files.map(
          (image) =>
            new Promise((resolve, reject) => {
              const fileReader = new FileReader();

              fileReader.onload = (file) => {
                resolve(file.target.result);
              };

              fileReader.onerror = (error) => reject(error);

              fileReader.readAsDataURL(image);
            })
        )
      ).then((base64Images) => {
        let body = { "files": base64Images }

        this.billingService.sendBillingRevaluation(body)
          .toPromise()
          .then(res => {
            this.closeModal()
          })
          .catch(err => {
            this.states.error = true
          })
      });
    }
Leticia Fatima
  • 512
  • 2
  • 4
  • 19