Below is code in which i am creating data for csv file and downloading csv file in zip folder:
generateCSVfiles()
{
this.studentdata.forEach(function (student)
{
this.service.getStudentDetails(student.studentId).subscribe
(res => {
var dataSet = JSON.parse (res);
// start
if (student.studentId == "Senior") {
const header = ["studentId","studentName","studentaddress", "studentmarks", "studentgrade"];
const replacer = (key, values) => values === null ? '' : values // specify how you want to handle null values here
this.seniordata = dataSet.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
this.seniordata.unshift(header.join(','));
this.seniordata = this.seniordata.join('\r\n');
}
else (student.studentId == "Junior") {
const header = ["studentId","studentName","studentaddress", "studentmarks", "studentgrade"];
const replacer = (key, values) => values === null ? '' : values // specify how you want to handle null values here
this.juniordata = dataSet.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
this.juniordata.unshift(header.join(','));
this.juniordata = this.juniordata.join('\r\n');
}
this.downloadzip();
}
}.bind(this)
}
public downloadzip()
{
let zip = new JSZip();
// Fill CSV variable
// i am getting two separate zip file by below logic but need to
//implement logic here to add two different file in one zip folder
zip.file( 'Studentrecord'+'.csv', this.juniordata);
zip.file( 'Studentrecord'+'.csv', this.seniordata);
zip.generateAsync({
type: "base64"
}).then(function (content) {
window.location.href = "data:application/zip;base64," + content ;
});
}
Above code working fine and able to download csv file inside zip folder when we got response data for one of junior or Senior student at a time. but when we received both junior and senior data at time then it downloading different zip file or sometimes only one zip file getting generated. but i want both file in one zip folder. can someone guide me how to download different csv file in one zip folder.
this.studentdata =[{studentId: "Senior"
StudentName: "Rock"},{studentId: "Junior"
StudentName: "John"}]
this type of data available in mentioned variable
dataset = [{studentId: "Senior"
StudentName: "Rock",studentaddress:"US",studentmarks:"56",studentgrade:"A"},{studentId: "Junior"
StudentName: "John",studentaddress:"UK",studentmarks:"59",studentgrade:"B"}]
this type of data coming from json
Here you have not represented your question correctly. Appreciate if you create demo on stackbliz. Any how, this is due to your iteration does not wait for the each observable to complete before moving on to the next one and you have already told in comment that is true.
First of all you need to understand the concept of observable, promise in rxjs. Once you get proper understanding go through the some extra operators like merge, mergeAll, forkjoin etc https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin
Now comes to your question: always use Promises for something like this, so below is an example of that, however, I'm sure there's an RXJS way to solve this as well, so you may want to explore that.
please go through http://bluebirdjs.com/docs/getting-started.html for iterating async in series.
import * as Bluebird from 'bluebird';
async generateCSVfiles() {
//first iterate through everything in series
await Bluebird.mapSeries(this.studentdata, (data) => {
return new Promise((resolve, reject) => {
this.service.getStudentDetails(student.studentId, student.StudentName).subscribe(res => {
...
//once you finish your conditionals
resolve();
})
});
});
//then, once complete, run download zip
this.downloadzip();
}