0

I'm making a chat bot where people get coins each 30 minutes, they can then spend those coins. When they spend those coins they need to be deducted, so I need to catch their command in my front-end and deduct the coins from their profile in my back-end.

This is a case of my switch case in which I catch the command that's being utilised

case `!gayOverlay`:
        const requiredKluiten = 50;

        fetch(`/api/users/${userstate.username}`) // fetch from Express.js server
          .then(response => response.json())
          .then(result => {
            if (result.instakluiten >= requiredKluiten) {
              client.action(channel, `${userstate[`display-name`]}, you've got enough instakluiten for this.`);

              const method = `PATCH`;
              const payload = {requiredKluiten};
              const body = JSON.stringify(payload);
              const headers = `Content-Type: application/json`;

              return fetch(`/api/users/${userstate.username}`, {method, body, headers})
                .then(r => console.log(`Result is `, d));
            }else{
              client.action(channel, `${userstate[`display-name`]}, you don't have enough instakluiten for this, you need ${requiredKluiten - result.instakluiten} more.`);
            }
          });
        break;

I'm using PATCH to update my viewers' coins (I read Please do not patch like an idiot, but people in the comments were also against the method, so I'm not sure what the correct way is anymore now...), when I send data with postman my req.body in my back-end is filled with the data I added. However, when I execute my function (which also should have data because of my payload), my req.body is an empty object. What am I doing wrong here?

This is what's happening on the server side

app.use(bodyParser.urlencoded({ extended: true }));

app.get('/api/users/:username', (req, res) => {
  let username = req.params.username;
  findUserInApi(username)
    .then(foundUser => {
      console.log(`foundUser is ${foundUser}`);
      if (!foundUser) {
        res.status(403).send('User not found in api yet');
      }else{
        res.json(foundUser);
      }
    });
});

Update

This is what's being returned in the then after my patch (changed it to PUT after the comment of Alex) https://puu.sh/shO57/362b639545.png

Update

Even when trying it like this (because of this post) it makes no difference

const data = JSON.stringify(payload);
const body = new FormData();
body.append(`json`, data);

Update

When using postman my body is always: {'requiredKluiten': 50}.

When I remove the headers (that were automatically set to application/x-www-form-urlencoded when choosing x-www-form-urlencoded to send my data) I get an empty object with Postman. When the headers are added again with x-www-form-urlencoded it works. When I select form-data however I get as req.body:

{ '------WebKitFormBoundarySAXAR2jfhUJt39US\r\nContent-Disposition: form-data; name': '"requiredKluiten"\r\n\r\n50\r\n------WebKitFormBoundarySAXAR2jfhUJt39US--\r\n' }

However, when adding the headers to my code, it still doesn't work when executing my fetch... I must still be doing something wrong :/...

This is what's being executed right now, any flaws to be spotted?

case `!gayOverlay`:
const requiredKluiten = 50;

  fetch(`/api/users/${userstate.username}`) // fetch from Express.js server
          .then(response => response.json())
          .then(result => {
            if (result.instakluiten >= requiredKluiten) {
              client.action(channel, `${userstate[`display-name`]}, you've got enough instakluiten for this.`);

              const method = `PUT`;
              const payload = {requiredKluiten};
              const body = JSON.stringify(payload);
              const headers = `Content-Type: application/x-www-form-urlencoded`;

              return fetch(`/api/users/${userstate.username}`, {method, body, headers})
                .then(d => console.log(`Result is `, d));
            }else{
              client.action(channel, `${userstate[`display-name`]}, you don't have enough instakluiten for this, you need ${requiredKluiten - result.instakluiten} more.`);
            }
          });
Community
  • 1
  • 1
Kevin
  • 1,219
  • 1
  • 16
  • 34
  • Hi Kevin, did you try to use the HTTP verb PUT ? It's commonly used to update entities into a REST Webservice. – Alex Nov 14 '16 at 08:51
  • And didn't saw that before, but you shouldn't compare the value you get from server with a const value client side. If I edit the requiredKluiten const in Javascript debugging, I can make you call the POST query even if I have 1 coin. – Alex Nov 14 '16 at 09:10
  • Oh that's actually a giant mistake... I shouldn't do that indeed... I put the const in my client side just to test the (requiredKluiten - currentKluiten). However, I looked up whether I should use PUT PATCH or POST. And I thought PATCH was the best way to go here. I would try PUT, but I don't _think_ that should be the solution, because via postman I get my req.body... Also, do you have any suggestion which approach would be the best to append the requiredKluiten to each command? Do I pass on the string of my command and check in my back-end: if(req.body.command === '!gayOverlay')? – Kevin Nov 14 '16 at 10:03
  • @Alex the put didn't make a difference. I updated my question with a screenshot of what's being returned. – Kevin Nov 14 '16 at 10:11
  • Yeah anyway it's not a big deal if you use PUT or PATCH, they're pretty the same, it's only about convention. In postman, do you have some headers set ? if it works with postman but not from your app, you should check for headers differences – Alex Nov 14 '16 at 13:06
  • I tried to be as complete as possible with my update @Alex, thanks for bearing with me so far. – Kevin Nov 14 '16 at 15:55
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128079/discussion-between-alex-and-kevin). – Alex Nov 14 '16 at 16:46

0 Answers0