0

I want to implement fetch method by myself with promises with builder pattern, the backend is fine. I tested it with postman and it works fine. I don't know what could be, I tried everything but I don't get any data.

I think the problem is that it doesn't properly transform my data to JSON or something.

Any help will be appreciated.

class Fetch {
    constructor(){
        this.url = null;
        this.result = null;
        this.method = null;
        this.header = null;
        this.body = null;
    }
    call(){
        return new Promise((resolve, reject) => {
            fetch(this.url, 
                  {method: this.method, header: this.header, body: this.body})
                .then(response => response.json())
                .then(data => {
                    this.result = data;
                    console.log(data);
                    resolve(data);
                })
        })
    }
}
class FetchBuilder {
    constructor(){
        this.customFetch = new Fetch();
    }
    request(url){
        this.flag = true;
        this.customFetch.url = url;
        return this;
    }
    method(method){
        this.customFetch.method = method;
        return this;
    }
    header(header){
        this.customFetch.header = header;
        return this;
    }
    body(body){
        if(!this.flag){
            this.customFetch.body = JSON.stringify(body);
        }
        return this;
    }
    query(obj){
    }
    send(){
        this.customFetch.call();
    }
}

const fetchObj = new FetchBuilder();
fetchObj.request('https://node-app-test-picsart.herokuapp.com/signin')
        .method('POST')
        .header({
            'Content-Type': 'application/json;charset=utf-8'
        })
        .body({
            email: 'bro@gmail.com',
            password: 'bro'
        })
        .send()

Header: enter image description here

Body enter image description here

Dave Newton
  • 158,873
  • 26
  • 254
  • 302

1 Answers1

1

Your issue lies in either the this.flag = true or if (!this.flag) { line what causes the body argument passed in the .body() method to be lost. So you're code is doing what you want but just not in the right way, as you are expecting a package to be sent to the endpoint.

So either change the boolean:

...
request(url) {
  this.flag = false;
  this.customFetch.url = url;
  return this;
}
...

Or the condition checking the boolean. The rest of your code works as expected.

...
body(body) {
  if (this.flag) {
    this.customFetch.body = JSON.stringify(body);   
  }
  return this;
}
...

Run the code below with the network tab in your developer tools opened to see that a request is made with the body you want to send.

class Fetch {
  constructor() {
    this.url = null;
    this.result = null;
    this.method = null;
    this.header = null;
    this.body = null;
  }
  call() {
    return fetch(this.url, {
        method: this.method,
        header: this.header,
        body: this.body
      })
      .then(response => response.json())
      .then(data => {
        this.result = data;
        console.log(data);
        return data;
      })
  }
}

class FetchBuilder {
  constructor() {
    this.customFetch = new Fetch();
  }
  request(url) {
    this.flag = true;
    this.customFetch.url = url;
    return this;
  }
  method(method) {
    this.customFetch.method = method;
    return this;
  }
  header(header) {
    this.customFetch.header = header;
    return this;
  }
  body(body) {
    if (this.flag) {
      this.customFetch.body = JSON.stringify(body);
    }
    return this;
  }
  query(obj) {}
  send() {
    this.customFetch.call();
  }
}

const fetchObj = new FetchBuilder();
fetchObj.request('https://node-app-test-picsart.herokuapp.com/signin')
  .method('POST')
  .header({
    'Content-Type': 'application/json;charset=utf-8'
  })
  .body({
    email: 'bro@gmail.com',
    password: 'bro'
  })
  .send()

In your Fetch().call() just return the fetch as it already returns a Promise, wrapping it like this would be an anti-pattern. You could also use the async / await syntax.

Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32