1

I am executing the following script and callbacks from XHR request increasing gradually(1, 2, 3.....etc) but network call happens only onetime.

class Service {

    profiles = [] //assume array contains objetcs
    xhr = new XMLHttpRequest();
    token = null;

    constructor(token) {
        this.xhr = new XMLHttpRequest();
        this.token = token
    }

    setInterval(res => {this.doFunc()}, 10000);

    doFunc() {
       if (this.profiles.length > 3) {
          this.doChoice(this.profiles[0]).then(response => {
              console.log(response); //printing only onetime
          });
       }
    }

    async doChoice(profile) {
        return await new Promise(resolve => {
            this.like(profile.id, response => {
                //code below is excuting gradually with interval method
                console.log('Liked');
                console.log(profile);
                this.profiles.splice(this.profiles.indexOf(profile), 1);
                resolve(JSON.parse(response));
            });
        })
    }

    like(id, subscribe = {res: ''}) {
        let url = 'https://someurl/' + id;

        this.xhr.open("GET", url);
        this.xhr.setRequestHeader("x-auth-token", this.token);
        this.xhr.addEventListener("readystatechange", function () {
            //code below is excuting gradually with interval method
            if (this.readyState === 4 && this.status === 200) {
                if (this.responseText) {
                    console.log(this.responseText); 
                    subscribe(this.responseText);
                }
            }
        });
        this.xhr.send();
    }
}

If someone can explain to me what I am doing wrong here that would be awesome!

Januka samaranyake
  • 2,385
  • 1
  • 28
  • 50
  • 1
    could you try `return await new Promise(....` – Bilal Siddiqui Oct 22 '19 at 13:46
  • @BilalSiddiqui is correct. `doChoice` returns `undefined`; you should be getting an error on the `.then` attached to it... – Heretic Monkey Oct 22 '19 at 14:07
  • @HereticMonkey yeah, I missed it when typing the code. but that's not the error – Januka samaranyake Oct 22 '19 at 14:09
  • The `setInterval` is called outside of any function or even the constructor. That seems odd. The function passed to `setInterval` takes no arguments, so putting `res =>` there is misleading. Also, the `subscribe` argument's default value is an object, but should probably be a function. Finally, you should consider creating a new `XMLHttpRequest` object every time (or use the new Fetch API). [Theoretically it's faster](https://stackoverflow.com/q/27888471/215552). – Heretic Monkey Oct 22 '19 at 14:16

1 Answers1

1

Don't store the XMLHttpRequest as a property. Instead, create it each time you want/need to send a request to the endpoint.

Furthermore, the code can be greatly simplified:

class Service {
    constructor(token) {
        this.token = token;
        this.profiles = [];
    
        setInterval(this.doFunc.bind(this), 10000);
    }
    doFunc() {
       if (this.profiles.length > 3) {
          this.doChoice(this.profiles[0]).then(profile => {
              console.log('Liked');
              console.log(profile);
              this.profiles.splice(this.profiles.indexOf(profile), 1);
          });
       }
    }
    doChoice(profile) {
        return new Promise((resolve, reject) => {
            let url = 'https://someurl/' + profile.id;
            let xhr = new XMLHttpRequest();
            
            xhr.open("GET", url);
            xhr.setRequestHeader("x-auth-token", this.token);
            xhr.addEventListener("readystatechange", function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    resolve(xhr.responseText);
                } else {
                  reject(new Error('XMLHttpRequest failed'));
                }
            });
            xhr.send();
        });
    }
}

As @HereticMonkey already pointed out, you also shouldn't use setInterval outside of the class' methods, because (a) it feels incredibly weird and (b) it executes a sideeffect (in your case, really multiple sideeffects) by just importing the class.

David
  • 3,552
  • 1
  • 13
  • 24