0

So, I am having some issues with functions and passing variables through them using an interval. While I can get values to pass through I can;t quite seem to get them updated.

Here is the main function:

    tradeSkill: (msg, what, type, amount, userData, stats) => {
     stats.actions--;
  if (stats.actions <= 0) {

        // The report DM
        userData.send({ embed: {
          color: 3447003,
          title: `Farming Report For ${type}`,
          fields: [{
            name: 'Stats',
            value:
            'Gathered: ' + stats.yield +
            '\nEXP Gained: ' + stats.exp,
          },
        ],
        },
        });

        //Reset stats for Report
        stats = {
          exp: 0,
          actions: amount,
          yield: 0,
        };

      }
    }

Here is how I'm passing it though:

autos(msg, what, type, amount, userData, stats);

Here is the autos function:

function autos(msg, what, type, amount, userData, stats) {
        if (userData.interval === undefined || userData.interval === false) {
          userData.interval = setInterval(() => {
            skills.tradeSkill(msg, what, type, amount, userData, stats);
            userData.intervalTime = Date.now();
          }, 6000);
          skills.tradeSkill(msg, what, type, amount, userData, stats);
        } else {
          var timing = userData.intervalTime + 5900 - Date.now();
          if (timing < 0) {
            timing = 0;
          }

          // Waits for current to end, then updates it.
          setTimeout(() => {
            clearInterval(userData.interval);
            userData.interval = setInterval(() => {
              skills.tradeSkill(msg, what, type, amount, userData, stats);
              userData.intervalTime = Date.now();
            }, 6000);
            skills.tradeSkill(msg, what, type, amount, userData, stats);
          }, timing);
        }
      }

My problem: In the first function, when stats.actions equal or less than 0 it will send a DM (using discord.js, but this isn't a discord.js problem so don't worry bout that). And then reset it back to the specified amount (which is always > 0). However, after it hits 0, it keeps sending DMs and will not set it to what is supposed to be properly. If I do console.log(stats.actions) before the if statement and inside of it, it always produces 0 before the if statement and will always produce a 10 inside the if statement (when it triggers the first time)

If might be hard to understand without the full code, however as its near total 1k lines, I am going to link it to paste bin:

Main Function: https://pastebin.com/XmmRqgsT

Secondary with the autos: https://pastebin.com/5xcG1qyx

William
  • 1,175
  • 2
  • 17
  • 32
  • TL;DR: `stats = {...}` creates a new object and assigns its reference to `stats`, which is a distinct variable (parameter) from the `stats` you pass to your function. So, after your function call, the original `stats` is unchanged. – RaphaMex Apr 13 '18 at 02:53
  • Okay, thanks for the information, but it didn't answer my question. How would I change the original? Since its a interval I can't set them inside of that function so I have to do it outside the function call, and pass in the information that way. – William Apr 13 '18 at 05:48
  • I think you should have a look at [this answer](https://stackoverflow.com/a/3638034/8122487) – RaphaMex Apr 13 '18 at 14:50
  • So basically I have to do it one by one, there is no updating them in bulk like this. I would have to do: `stats. exp = 0` so on and so forth. Which I guess doesn't really increase my lines of code, just kind of annoying lol. – William Apr 13 '18 at 21:22
  • Let me put it in an answer – RaphaMex Apr 13 '18 at 22:06

1 Answers1

1

Indeed you should assign values of properties with = instead of assigning a new object.

If it is supported by your engine, you can use Object.assign() instead of =. It makes a shallow copy (not a deep copy), which works for you because your object is flat.

I have simplified your example to make it work here:

const stats = {
    exp: 0,
    actions: 2,
    yield: 0
};
const skills = {
    tradeSkill: (amount, stats) => {
        stats.actions--;
        if (stats.actions <= 0) {
            //Reset stats for Report
            Object.assign(stats, { // properties of 2nd object are copied into 1st object
                exp: 0,
                actions: amount,
                yield: 0
            });
        }
        return stats;
    }
}
console.log(skills.tradeSkill(10, stats)); // { exp: 0, actions: 1, yield: 0 }
console.log(skills.tradeSkill(10, stats)); // { exp: 0, actions: 10, yield: 0 }
console.log(skills.tradeSkill(10, stats)); // { exp: 0, actions: 9, yield: 0 }

To understand the difference, you can check this answer.

RaphaMex
  • 2,781
  • 1
  • 14
  • 30
  • Is there a real difference doing it this what, rather than doing them like: `stats.exp = 0`? Either way it's good to know. I will put this as the answer, as it does work, I'm just doing it differently. Lol – William Apr 14 '18 at 01:25
  • @William: `Object.assign` allows you do bulk changes, which is much easier to read than assigning properties on multiple lines. `Object.assign` copies all enumerable properties values and their descriptors, which is technically a bit more than just copying values. – RaphaMex Apr 14 '18 at 04:00