How to replace undefined with a string

I’ve recently asked this issue on stackoverflow, but so far the issue has not been fixed yet.

So. I tried using this code

for (let i = 0; i < award.length; i++) {
        if (i == undefined) {
          return this.client.config.emojis.letters.y;
        }
        if (data.memberData.workStreak > i) {
          let letter = Discord.Util.parseEmoji(award[i]).name.split("_")[1];
          award[i] = ":regional_indicator_" + letter + ":";
        }
      }

But its still saying undefined

It looks like letter (not i) can be undefined when it is used here. According to your code, i will never be undefined—you assign it right off the bat with let i = 0.

so what’s the solution? I’m not really good at coding. I start using javascript like a month ago.

Can you try logging the value of i at different places like in the for loop and in the if statement and see what you get? And also, are you trying to replace undefined with the letter y?

Yes. on my config file the y stands for <:white:685784254029758520>

I put console.error(award[1]) on the script and the output is

:regional_indicator_undefined:
<:grey:685784080637231208>
<:grey:685784080637231208>
<:grey:685784080637231208>
<:grey:685784080637231208>

EDIT: The pic on this topic is the old pic. I made a small changes with it and here is the new look:

it’s still saying undefined

Here is the full code in case you need it

const Command = require("../../base/Command.js"),
  Discord = require("discord.js");

class Work extends Command {
  constructor(client) {
    super(client, {
      name: "work",
      description: language => language.get("WORK_DESCRIPTION"),
      usage: language => language.get("WORK_USAGE"),
      examples: language => language.get("WORK_EXAMPLES"),
      dirname: __dirname,
      enabled: true,
      guildOnly: true,
      aliases: ["salaire", "salary", "travail"],
      memberPermissions: [],
      botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
      nsfw: false,
      ownerOnly: false,
      cooldown: 3000
    });
  }

  async run(message, args, data) {
    // if the member is already in the cooldown db
    let isInCooldown = data.memberData.cooldowns.work;
    if (isInCooldown) {
      /*if the timestamp recorded in the database indicating 
            when the member will be able to execute the order again 
            is greater than the current date, display an error message */
      if (isInCooldown > Date.now()) {
        return message.channel.send(
          message.language.get(
            "WORK_ERR_COOLDOWN",
            message.language.convertMs(isInCooldown - Date.now())
          )
        );
      }
    }

    if (Date.now() > data.memberData.cooldowns.work + 24 * 3600000) {
      data.memberData.workStreak = 0;
    }

    // Records in the database the time when the member will be able to execute the command again (in 12 hours)
    let toWait = Date.now() + 21600000;
    data.memberData.cooldowns.work = toWait;
    data.memberData.markModified("cooldowns");

    data.memberData.workStreak = (data.memberData.workStreak || 0) + 1;
    await data.memberData.save();

    let embed = new Discord.MessageEmbed()
      .setFooter(
        message.language.get("WORK_FOOTER"),
        message.author.displayAvatarURL()
      )
      .setColor(data.config.embed.color);

    let award = [
      this.client.config.emojis.letters.s,
      this.client.config.emojis.letters.s,
      this.client.config.emojis.letters.s,
      this.client.config.emojis.letters.s,
      this.client.config.emojis.letters.s
    ];
    let won = 200;

    if ((data.memberData.workStreak || 0) >= 5) {
      won += 400;
      embed
        .addField(
          message.language.get("WORK_CLAIMED_HEADINGS")[0],
          message.language.get("WORK_CLAIMED_SALARY", won)
        )
        .addField(
          message.language.get("WORK_CLAIMED_HEADINGS")[1],
          message.language.get("WORK_AWARD")
        );
      data.memberData.workStreak = 0;
    } else {
      for (let i = 0; i < award.length; i++) {
        if (i == undefined) {
          return this.client.config.emojis.letters.y;
        }
        if (data.memberData.workStreak > i) {
          let letter = Discord.Util.parseEmoji(award[i]).name.split("_")[1];
          award[i] = ":regional_indicator_" + letter + ":";
        }
      }
      embed
        .addField(
          message.language.get("WORK_CLAIMED_HEADINGS")[0],
          message.language.get("WORK_CLAIMED_SALARY", won)
        )
        .addField(
          message.language.get("WORK_CLAIMED_HEADINGS")[1],
          award.join("")
        );
    }

    data.memberData.money = data.memberData.money + won;
    data.memberData.save();

    let messageOptions = { embed };
    if (!data.userData.achievements.work.achieved) {
      data.userData.achievements.work.progress.now += 1;
      if (
        data.userData.achievements.work.progress.now ===
        data.userData.achievements.work.progress.total
      ) {
        messageOptions.files = [
          {
            name: "unlocked.png",
            attachment: "./assets/img/achievements/achievement_unlocked1.png"
          }
        ];
        data.userData.achievements.work.achieved = true;
      }
      data.userData.markModified("achievements.work");
      data.userData.save();
    }

    // Send the embed in the current channel
    message.channel.send(messageOptions);
  }
}

module.exports = Work;

Are you able to link some of Command.js?

The issue is the Discord.Util to which is calling “letter” does not pass a string.
Try using:

award[i] = ":regional_indicator_" + JSON.stringify(letter) + ":";

I hope this helps!

JavaScript will already attempt to “stringify” variables when they’re being concatenated to other strings. Whether or not JSON.stringify is specifically called is another story (I think Object.prototype.toString might be called). I suspect the line will be functionally the same compared to what it was before.

@Veinify, I suggest you try out the following:

// Should be an object with a 'name' attribute
const parsed = Discord.Util.parseEmoji(award[i]);

console.debug("parsed:", parsed);
console.debug("Should be an object with a 'name' attribute");

// Should be an array with at least two entries
const nameParts = parsed.name.split("_");

console.debug("nameParts:", nameParts);
console.debug("Should be an array with at least two entries");

// Should be a string representation of a valid emoji shortcode
const letter = ":regional_indicator_" + nameParts[1] + ":";

console.debug("letter:", letter);
console.debug("Should be a string representation of a valid emoji shortcode");

That’s not what i wanted. I want the undefined replaced with this.client.config.emojis.letters.y. not removing the undefined.

Hey, at this code
`for (let i = 0; i < award.length; i++) {

    if (i == undefined) {
      return this.client.config.emojis.letters.y;
    }
    if (data.memberData.workStreak > i) {
      let letter = Discord.Util.parseEmoji(award[i]).name.split("_")[1];
      award[i] = ":regional_indicator_" + letter + ":";
    }
  }`

You used if (i == undefined) , shouldn’t that be if (award[i] == undefined)?

it worked but it send this.client.config.emojis.letters.s instead …y. it’s not the wrong emoji because on my config file i put a different emojiId

letters: {
      s: "<:grey:685784080637231208>",
      y: "<:white:685784254029758520>"
},

here is the project if you want to look futher into it

Can you show the message? Like the result and what the y letter and s letter should be?