Function unable to use string parsed from address bar as argument

Viewed 49

I'm rebuilding a website which contains basic introductions to characters in the fighting game Tekken 7. I've stored all the characters and their data as objects and set up a function to display a character's data on a web page, accepting that character's name as its sole argument.

/* DECLARATIONS */
// Profile
let charName = document.getElementById("char-name");
let charNickname = document.getElementById("nickname");

let charFlag = document.getElementById("flag");
let charImg = document.getElementById("image");

let charAge = document.getElementById("age");
let charCountry = document.getElementById("country");
let charFightingStyle = document.getElementById("fighting-style");
let charDebut = document.getElementById("first-appearance");

// Scores
let charOffense = document.getElementById("offense");
let charDefence = document.getElementById("defence");
let charRange = document.getElementById("range");
let charPunishment = document.getElementById("punishment");

let charGimmicks = document.getElementById("gimmicks");
let charExecution = document.getElementById("execution");
let charHurtbox = document.getElementById("hurtbox");

// Playstyle and Intro
let charPlaystyle = document.getElementById("playstyle");
let charIntro = document.getElementById("introduction");


/* DISPLAY FUNCTION */
const display = character => {
    charName.innerHTML = character.name;
    charNickname.innerHTML = character.nickname;

    charFlag.src = character.flag;
    charImg.src = character.image;

    charAge.innerHTML = character.age;
    charCountry.innerHTML = character.country;
    charFightingStyle.innerHTML = character.fightingStyle;
    charDebut.innerHTML = character.debut;

    charOffense.innerHTML = character.offense;
    charDefence.innerHTML = character.defence;
    charRange.innerHTML = character.range;
    charPunishment.innerHTML = character.punishment;

    charGimmicks.innerHTML = character.gimmicks;
    charExecution.innerHTML = character.execution;
    charHurtbox.innerHTML = character.hurtbox;

    charPlaystyle.innerHTML = character.playstyle;
    charIntro.innerHTML = character.introduction;
}

/* CHARACTER EXAMPLE */
// Jin Kazama
const jin = {
    // Profile
    name: "Jin Kazama",
    nickname: "The Child of Destiny",

    flag: "../img/flagicons/japan.svg",
    image: "../img/characters/jin.png",

    age: 21,
    country: "Japan",
    fightingStyle: "Traditional karate",
    debut: "<em>Tekken 3</em>",

    // Scores
    offense: 9,
    defence: 10,
    range: 8,
    punishment: 8,

    gimmicks: 3,
    execution: 3,
    hurtbox: 3,

    // Playstyle
    playstyle: "Versatile, keep-out, Mishima",
    introduction: "<p>Versatile character who performs at his best in the mid-range, armed with good poking, great counter hit tools, great damage output, variety in his throws and a unique parry that deals with all highs and mids except projectiles (fireballs). While his Mishima-style tools are not quite as effective as those of the out-and-out Mishima characters, he makes up for it with other situational moves that plug those weaknesses. He does, however, lack range on a few key punishers.</p>",
};

/* CALLING DISPLAY FUNCTION */
let params = (new URL(document.location)).searchParams;
let char = params.get("view");
display(char);

The code parses out the "view" parameter from the address bar and is supposed to return it to the function as an argument. For example, if the address bar has the URL .../guides/character.html?view=jin, the code should ideally parse the jin value and pass it back to the function as its argument to display this. I even tested the char argument with console.log to see if the value was passed without any issues and it printed jin as expected.

However, when the code runs by itself, it's somehow unable to use the value as an argument and instead passes back an undefined object, with the console showing the error message GET [file path]/guides/undefined net::ERR_FILE_NOT_FOUND as shown here.

Could anyone help me understand why this is happening? I'm still learning some of the inner workings of JavaScript so I'm completely stumped.

1 Answers

You're very close to having this correct. I believe the problem you are facing is that you are expecting the string of "jin" to reference your const jin. However, this isn't really how the JS rendering engine works-- the string of "jin" is being passed simply as a string, which is why all your values are showing up undefined-- because the string "jin" has none of the properties you are seeking.

This will log the string "jin" passed, and then several undefined:

const jin = {
    // Profile
    name: "Jin Kazama",
    nickname: "The Child of Destiny",

    flag: "../img/flagicons/japan.svg",
    image: "../img/characters/jin.png",

    age: 21,
    country: "Japan",
    fightingStyle: "Traditional karate",
    debut: "<em>Tekken 3</em>",

    // Scores
    offense: 9,
    defence: 10,
    range: 8,
    punishment: 8,

    gimmicks: 3,
    execution: 3,
    hurtbox: 3,

    // Playstyle
    playstyle: "Versatile, keep-out, Mishima",
    introduction: "<p>Versatile character who performs at his best in the mid-range, armed with good poking, great counter hit tools, great damage output, variety in his throws and a unique parry that deals with all highs and mids except projectiles (fireballs). While his Mishima-style tools are not quite as effective as those of the out-and-out Mishima characters, he makes up for it with other situational moves that plug those weaknesses. He does, however, lack range on a few key punishers.</p>",
};

const display = character => {
    console.log(character);
    console.log(character.name);
    console.log(character.nickname);

    console.log(character.flag);
    console.log(character.image);

    console.log(character.age);
    console.log(character.country);
    console.log(character.fightingStyle);
    console.log(character.debut);

    console.log(character.offense);
    console.log(character.defence);
    console.log(character.range);
    console.log(character.punishment);

    console.log(character.gimmicks);
    console.log(character.execution);
    console.log(character.hurtbox);

    console.log(character.playstyle);
    console.log(character.introduction);
}

display('jin');

So how to fix it? Your easiest bet, most likely, is to create a giant config object called characters, that contains a property for each character's name that the contains an object with all their property. By using an object you can reference by string the character to get the object with all the properties:

Displays the whole object, followed by the individual stats/properties:

const characters ={
    jin: {
        // Profile
        name: "Jin Kazama",
        nickname: "The Child of Destiny",

        flag: "../img/flagicons/japan.svg",
        image: "../img/characters/jin.png",

        age: 21,
        country: "Japan",
        fightingStyle: "Traditional karate",
        debut: "<em>Tekken 3</em>",

        // Scores
        offense: 9,
        defence: 10,
        range: 8,
        punishment: 8,

        gimmicks: 3,
        execution: 3,
        hurtbox: 3,

        // Playstyle
        playstyle: "Versatile, keep-out, Mishima",
        introduction: "<p>Versatile character who performs at his best in the mid-range, armed with good poking, great counter hit tools, great damage output, variety in his throws and a unique parry that deals with all highs and mids except projectiles (fireballs). While his Mishima-style tools are not quite as effective as those of the out-and-out Mishima characters, he makes up for it with other situational moves that plug those weaknesses. He does, however, lack range on a few key punishers.</p>",
    }
};

const display = character => {
    console.log(character);
    console.log(character.name);
    console.log(character.nickname);

    console.log(character.flag);
    console.log(character.image);

    console.log(character.age);
    console.log(character.country);
    console.log(character.fightingStyle);
    console.log(character.debut);

    console.log(character.offense);
    console.log(character.defence);
    console.log(character.range);
    console.log(character.punishment);

    console.log(character.gimmicks);
    console.log(character.execution);
    console.log(character.hurtbox);

    console.log(character.playstyle);
    console.log(character.introduction);
}

display(characters['jin']);

Related