0

Here is my code:

function id(file) {
  return new Promise((resolve, reject) => {
    reader = new FileReader();
    reader.onload = function(e) {
      parsedLines = e.target.result.split(/\r|\n|\r\n/);
      resolve(parsedLines);
    };
    reader.readAsText(file);
  });
}

document.getElementById('fileInput').addEventListener('change', function(e) {
  var file = e.target.files[0];

  if (file != undefined) {
    id(file).then(id => {
      console.log(id)
      console.log(parsedLines)
      console.log(typeof id);

      var idInt = id.map(Number);

      var idFiltered = id.filter(function(v){return v!==''});

      console.log(idFiltered)

      idFiltered.forEach(idFiltered => {
        getRelease(idFiltered);
      });
    });
  }
});

function getRelease(idFiltered) {
  return fetch(`https://api.*******.com/releases/${idFiltered}`, {
    'User-Agent': '*******/0.1',
  })
  .then(response => response.json())
  .then(data => {
    if (data.message === 'Release not found.') {
      return { error: `Release with ID ${idFiltered} does not exist` };
    } else {
      const id = data.id;
      const artists = data.artists ? data.artists.map(artist => artist.name) : [];
      const country = data.country || 'Unknown';
      const released = data.released_formatted || 'Unknown';
      const genres = data.genres || [];
      const styles = data.styles || [];
      const tracklist = data.tracklist ? data.tracklist.map(track => track.title) : [];

      console.log(idFiltered);
      console.log(artists, country, released, genres, styles, tracklist)

      const rows = [
        [idFiltered, artists, country, released, genres, styles, tracklist],

      ];

      const ROW_NAMES = ["Release ID", "artists", "country", "released", "genres", "styles", "tracklist"];

      console.log(rows);

      let csvContent = "data:text/csv;charset=utf-8,"
      + ROW_NAMES + "\n" + rows.map(e => e.join(",")).join("\n");

      console.log(csvContent);

      var encodedUri = encodeURI(csvContent);
      var link = document.createElement("a");
      link.setAttribute("href", encodedUri);
      link.setAttribute("download", "my_data.csv");
      document.body.appendChild(link); // Required for FF

      link.click();

    }
  });
}

When I console.log(csvContent) I am getting one line each time, and it is happening 5 times instead of once. I think that is the nub of the problem as I seem to be cycling through let csvContent 5 times instead of just once. Perhaps I should separate that out into its own function?

I found this, which is very similar to my code, and probably where I got mine from. That seems to be exactly what I am trying to do, so IDK what the problem is.

You can do this in native JavaScript. You'll have to parse your data into correct CSV format as so (assuming you are using an array of arrays for your data...

I tried separating out all the csvContent stuff into its own function download_csv() , and it runs fine, but no csv file comes down now and I'm not sure how to do that.

Then I tried doing

  idFiltered.forEach(idFiltered => {
    getRelease(idFiltered);
  });
  download_csv();

...but I got

Uncaught (in promise) ReferenceError: download_csv is not defined

Any help please? TIA

Edit: idFiltered.forEach is running getRelease for each ID, isn't it? So surely I need to split off let csvContent and so on into its own function, as that part should only run once, right?

Edit2: I am trying to write some separate function to take care of the download independently, but I however I write it I keep getting "Uncaught TypeError: rows is undefined"

Edit3: I've given up trying to write a separate function to take care of the download independently, as I can't seem to do it without leaving some undefined variable. I'm totally at a loss how to do this now.

Edit4: OK, I have managed to carve off the download function without adding any errors, though now I don't get a download at all. I am fairly sure the download function needs to be separated off in order not to occur once per line though. So now, I have the following, though it never actually runs:

function download(rows) {
  const ROW_NAMES = ["Release ID", "artists", "country", "released", "genres", "styles", "tracklist"];

  console.log(rows);

  let csvContent = "data:text/csv;charset=utf-8,"
  + ROW_NAMES + "\n" + rows.map(e => e.join(",")).join("\n");

  console.log(csvContent);

  var encodedUri = encodeURI(csvContent);
  var link = document.createElement("a");
  link.setAttribute("href", encodedUri);
  link.setAttribute("download", "my_data.csv");
  document.body.appendChild(link); // Required for FF

  link.click();
}
double-happiness
  • 137
  • 1
  • 12
  • But where did you define the `download_csv()` function? – Kokodoko Nov 01 '21 at 15:15
  • @Kokodoko - I tried writing it as a separate function, to contain all the `let csvContent...` stuff. I figured, since `idFiltered.forEach(idFiltered)...` is running that stuff once for every line, it needs to be in its own function, right? But I don't know what I am doing so I just put it back as it originally was. – double-happiness Nov 01 '21 at 15:18

0 Answers0