0

We have a database of words and categories. My requirement is to allow word admin to add many words at once through a csv file. Currently we have a system that can add a word at once. So my idea was to just call that function as many times as words in the csv file.

Here is my component file constructor and injections

export class AdminComponent implements OnInit {
  currentJustify = 'start';
  processing = false;
  error = false;
  errorAdd = false;
  word: IWord;
  showTable = false;


  @Input() wordArea: string;
  @Input() idArea: number;

  addWordMessage: string;


  categoryItems: string[] = ['Category...', 'awl','stem', 'hi', 'med', 'low'];
  category: string = this.categoryItems[0];

  sessionHistory: string[] = [];
  index = 1;

  constructor(private _admin: AdminService, public router: Router) { }

Now this is the function I'll be calling iteratively.

 addWord(wordArea:string, category:string): void {
    this.processing = true;
    this.error = false;
    this.errorAdd = false;
    this._admin.postWord(wordArea, category)
      .subscribe
      (res => {
        this.processing = false;
        this.sessionHistory[this.index] = wordArea + ' is added to ' + category + ' category.'
        this.index++;
      },
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log('Client-side Error occured');
        } else {
          this.errorAdd = true;
          this.processing = false;
          console.log('Server-side Error occured');
        }
      }
      );
  }

And these are the functions I've created so far:

 fileUploadListener($event:any):void{

    this.csvadd($event.target, this.addWord);
    console.log('out of it');

   }

  csvadd(csv: any, callback): void { console.log('here')
    var file:File = csv.files[0];
    var self = this;
    var reader:FileReader = new FileReader();
    var wordArea:string;
    var category:string;
    var array;
    var fields;
    this.processing = true;
    this.error = false;
    this.errorAdd = false;

    console.log('here 2')

    reader.readAsText(file);

    reader.onloadend = function (e) {
             var csvData = reader.result;
             console.log(csvData);
             fields = csvData.split('\n');


             for (let i in fields) {
              console.log('in loop'); 
              var array = fields[i].split(',');
              console.log(array);
              wordArea=array[0];
              console.log(wordArea);
              category=array[1];
              console.log(category);
              callback(wordArea, category);
              console.log('final')}

         };

         reader.onerror = function () {
             console.log('Unable to read ' + file);
         };



  }

From what I've understood from figuring out how to use Typescript and Javascript, you have to use a callback function for this because otherwise you can't get the information from the file reader. So I did that, but that did not work.

Am I going about this whole thing correctly? Should I take another approach, or is there something here I'm missing?

Thank you!

Jcvf90
  • 21
  • 1
  • 3
  • You really should add a way to submit the words at once and let the backend do the work of inserting them correctly into the database. – Andreas Mar 03 '18 at 08:13

1 Answers1

0

Send your callback function with bind or using arrow since the this will refer to the function and not the class that you want it to refer to.

this.csvadd($event.target, this.addWord.bind(this));

Or

this.csvadd($event.target, (wordArea, category)=>this.addWord(wordArea,category));

Also change

 reader.onloadend = function(e){}

to

 reader.onloadend =(e)=>{}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • Thank you. It worked resolving the error. Do you see any other errors? Because now it only adds the last word of the csv file I upload. I doesn't add all of words. Thank you! – Jcvf90 Mar 03 '18 at 14:44
  • no.. am not sure about the logic you have used. You will have to debug it..GOod luck – Suraj Rao Mar 03 '18 at 14:48
  • Ok. One last question. Could it be a problem of async again? Since addWord calls an http service, so it's only doing the last one? How would I get it to do each call to addword sequentially? – Jcvf90 Mar 03 '18 at 16:13
  • Yes. https://stackoverflow.com/questions/11488014/asynchronous-process-inside-a-javascript-for-loop use forEach of array – Suraj Rao Mar 03 '18 at 16:20
  • Hey, so I tried the forEach, and I'm still only getting the last entry in the csv to process. Is there any way to make the for loop stop until the callback function to addword is done ? Thank you – Jcvf90 Mar 04 '18 at 20:20