Friday 17 August 2018

Spot The Bug: X marks the spot!

Good evening, and we're back for some Spot The Bug madness.

No bugs are safe!


I've got somber news. Jim "The Anvil" Neidhart, Canadian professional wrestler, just passed away on the 13th of this month and with him, a generous chunk of my childhood. I used to spend weekends glued to the TV gleefully watching the big man slam his opponents to the canvas and execute moves a man his size had no right to be making. (Ever seen a 280 pound standing dropkick? Looks as painful as it sounds.) I'd listen entranced at the mad cackles and the trademark snarls during his interviews. And I would go absolutely apeshit when he hit The Anvil Flattener.

Looted from wwe.com

It was reported that he fell and hit his head at home, then passed away at the age of 63. Guess Jim Deidhart, eh? (OK, ouch, that pun was lame even by my standards...)

Anyway. I'm getting all nostalgic just talking about it. So I was hacking together this little page which would feature a list of my favorite YouTube videos featuring Jim Neidhart. And there'd be a screen that would show the video I clicked on. I copied and pasted some old jQuery that would render a table off a JSON object containing all the data; namely, the title and links of the YouTube videos.

Here's the code. I made the JSON object smaller for brevity.
<!DOCTYPE html>
<html>
    <head>
        <title>The Pink and Black Attack!</title>
        <style>
            body
            {
                background-color: #DD8888;
            }

            #tblMain tr td b
            {
                color: #000000;
            }

            #tblMain tr td b
            {
                color: #FFDDDD;
            }

            button
            {
                background-color: #FFDDDD;
                color: #DD8888;
                font-weight: bold;
            }

            div
            {
                width: 300px;
                float: left;
            }
        </style>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

        <script>
        $(document).ready(function (x)
        {
            var pbdata =
            [
                {"desc":"Anvil vs Bad News Brown", "link":"7nhMnYjIFYk"},
                {"desc":"Anvil challenges Bulldog", "link":"W3WYWiqkL3M"},
                {"desc":"Classic Promo", "link":"glFtNFtpEPk"},
                {"desc":"Anvil vs Mr Perfect", "link":"0llHaAsPeeE"},
                {"desc":"Anvil shoot interview", "link":"VAoLzHf1UUY"},
                {"desc":"Anvil promo for Bad News Brown", "link":"yeEF-TAmE6c"},
                {"desc":"Hart Foundation promo", "link":"srSJUctZHf4"},
                {"desc":"Hart Foundation Tag Champs", "link":"GRy-w1qjW2g"},
            ];

            var tr;
            var td;
            var btn;

            pbdata.forEach
            (
                function(x)
                {
                    tr = $("<tr></tr>");

                    td = $("<td></td>");
                    td.html(x.desc);   
                    tr.append(td);

                    btn = $("<button>Go</button>");
                    btn.click(function(x)
                    {
                        $("#ifmPlay").attr("src", "http://www.youtube.com/embed/" + x.link);
                    }
                    );

                    td = $("<td></td>");
                    td.append(btn);

                    tr.append(td);

                    $("#tblMain").append(tr);
                }
            )           
        });

        </script>
    </head>
    <body>
        <div>
            <table id="tblMain">
                <tr>
                    <td><b>Description</b></td>
                    <td><b>Link</b></td>
                </tr>
            </table>
        </div>
        <div>
            <iframe id="ifmPlay" width="420" height="315" src="">
            </iframe>
        </div>   
    </body>
</html>


What went wrong

The table rendered just fine. Pink and black, nice huh? Problem was, no video would play when I clicked the buttons.

Why it went wrong

See this? That's what I did to make the button play the video. That was the problem.
btn.click(function(x)
{
    $("#ifmPlay").attr("src", "http://www.youtube.com/embed/" + x.link);
}


I'm really, really used to making callbacks like this...
function(x)
{

}


...so much so I totally forgot this was already within a callback of its own, also using x as the name of the parameter! So x, in this new scope, was referencing the event of the mouseclick instead of the current element in the pbdata object!

                function(x)
                {
                    tr = $("<tr></tr>");

                    td = $("<td></td>");
                    td.html(x.desc);   
                    tr.append(td);

                    btn = $("<button>Go</button>");
                    btn.click(function(x)
                    {
                        $("#ifmPlay").attr("src", "http://www.youtube.com/embed/" + x.link);
                    }
                    );

                    td = $("<td></td>");
                    td.append(btn);

                    tr.append(td);

                    $("#tblMain").append(tr);
                }


So instead of the URL being "http://www.youtube.com/embed/7nhMnYjIFYk" for example, it would only be "http://www.youtube.com/embed/", which would still get to YouTube, but return absolutely nothing but a blank screen. And there would be no error message in the console because x was still a valid object.

How I fixed it

This one was straightforward. Merely use a different parameter name.
btn.click(function(y)
{
    $("#ifmPlay").attr("src", "http://www.youtube.com/embed/" + x.link);
}


And all's right with the world!

Conclusion

Getting caught mixing up your scopes is a fairly common problem in jQuery, or even just JavaScript. Luckily, this took me all of five minutes to solve. But this can be a right headscratcher if you see no error messages and the problem looks like the videos themselves.

x-quisitely yours,
T___T

No comments:

Post a Comment