How can jQuery append() with backquote (``) miss/won't render a string variable?

812 Views Asked by At

I'm building several carousels on a webpage with jQuery by calling all the information I need from YouTube with the Youtube Data API v3. After doing the designing and the functions I'm struggling with one simple thing that I cannot understand.

I use append(``) so that I can append all the HTML that I need to the element that I want, and also inserting other informations with the variables in the ${var} notation.

Everything works fine EXCEPT for a single string variable preview. It's like it not recognized as a variable and in the final output is rendered like a string chunck. Now some code.

This is the preparation for calling the function that loads everything:

jQuery(document).ready(function () {
    var apikey = 'my-api-key';
    var URL = 'https://www.googleapis.com/youtube/v3/playlistItems';
    var playlists = {
        1: 'PL549CFEF61BF98279',
        2: 'PLX_IxBH-yGtonzSE2zyplhI2oky7FWvbE',
        3: 'PL038B3F56D598DD61',
        4: 'PLDDFDDD10E5584056',
        5: 'PLD4F65416EB11640F',
    }

    loadVids(apikey, URL, playlists);
});

Next loadVids, for every youtube playlist call getJSON() and retrieve the data:

function loadVids(apikey, URL, playlists) {
    for (const menuid in playlists) {
        var options = { part: 'snippet', key: apikey, maxResults: 20, playlistId: playlists[menuid] }
        jQuery.getJSON(URL, options, function (data) {
            resultsLoop(data, menuid, apikey);
        });
    }
}

then resultLoop using each() puts all the information inside some HTML to be appended somewhere in the webpage (i stripped all the original attributes to keep it readable).

function resultsLoop(data, menuid) {
    jQuery.each(data.items, function () {

        var alttext = this.snippet.title;
        var title = alttext.substring(0, 57) + '…'
        var vid = this.snippet.resourceId.videoId;
        var preview = this.snippet.thumbnails.standard.url;

        jQuery("#carousel-" + menuid + " ul")
        .append(`
<li>
    <article>
        <div>
            <a href="//www.youtube.com/watch?v=${vid}&fs=1&autoplay=0&rel=0">
                <img alt="${alttext}" src="${preview}">
            </a>
        </div>
        <div>
            <h4><a href="/index.php?Itemid=${menuid}" title="${alttext}">${title}</a></h4>
        </div>
    </article>
</li>
`);
    });
}

At the end of it the <img> tag is

<img alt="some text" src="/$%7Bpreview%7D">

I tried to:

  • change the name of the variable
  • console logging it before, after append(), without issues
  • typeof says it's a normal string
  • it gives me the same result on every browser

I really don't understand what I'm doing wrong, and only preview doesn't work, all the other variables in the append() are working properly.

2

There are 2 best solutions below

1
On

Why you are not using concat as you have already did for jQuery("#carousel-" + menuid + " ul") !!

Example: (Please use this code for append and check, I have used single quote and not backquote as it is not accepted by js validation)

jQuery("#carousel-" + menuid + " ul").append('<li><article><div><a href="//www.youtube.com/watch?v=${vid}&fs=1&autoplay=0&rel=0"><img alt="'+alttext+'" src="'+preview+'"></a></div><div><h4><a href="/index.php?Itemid='+menuid+'" title="'+alttext+'">'+title+'</a></h4></div></article></li>');

and remove all white spaces from the append string. I hope it is what looking for.

0
On

Just to let you know, all the above was working on a Joomla page.

Taking all the code, apart from the jQuery(document).ready(function(){...loadVids()...}, and putting it on a .js file resolved everything.

I think there is some filter that won't let you inject external resources like https://i.ytimg.com/vi/lmuUD9_eDnY/sddefault.jpg in the page with javascript alone (and that's clever), but the filter doesn't apply if you include a .js file within the website itself.

A mediocre workaround for a mediocre javascript code. Thanks to Rory in the comments that gave me some insight.