How to access elements rendered into the page with Mustache using jQuery

678 views Asked by At

I am rendering some content into my page using a mustache template and ajax. I would then like to interact with some of the elements (hide them depending on page position) using another function (componentLoaded).

Obviously this function needs to run after the items are rendered on the page, but how is this done? I'm trying to use the promise deferred object on my ajax calls but this doesn't seem to work:

var template = null;

//Get Template
function getTemplate() {
    return $.get('mustache/components/block.mustache', function(response) {
         template = response;
    }).then(renderComponent());
}

//Render Template
function renderComponent() {
    // Get Data
    return $.ajax('JSON/testData.json',{
        dataType: 'json',
        success: function(data) {
            if(template != null) {
                for(var i = 0; i < data.blocks.length; i++) {

                    renderTemplate(template, data.blocks[i], $('#container'));
                }
            }
            else {
                console.error('Error: Template failed to load');
            }
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console.error('Ajax Error: ' + xhr.status + ' ' + thrownError);
        }
    }).then(componentLoaded());
}

/**
 * Render the template onto the page
 * @param template, The mustache template to render the data with
 * @param data, {{object}} The data to render into the template
 * @param target, {{object}} The jQuery object for the element to append the rendered data to
 */
function renderTemplate(template, data, target) {
    var rendered = Mustache.render(template, data);

    target.append(rendered);
}

/**
 * Render the component
 */
$(document).ready(function() {
    getTemplate();
});

Please note that componentLoaded() is a function in another file.

2

There are 2 answers

0
Dominic On BEST ANSWER

Why not call componentLoaded() inside the success function?

function renderComponent() {
    // Get Data
    return $.ajax('JSON/testData.json',{
        dataType: 'json',
        success: function(data) {
            if(template != null) {
                for(var i = 0; i < data.blocks.length; i++) {

                    renderTemplate(template, data.blocks[i], $('#container'));
                }
                componentLoaded();
            }
            else {
                console.error('Error: Template failed to load');
            }
            // or here
            // componentLoaded();
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console.error('Ajax Error: ' + xhr.status + ' ' + thrownError);
        }
    });
}
0
Dominic On

By the way, the answer to your question when you really want to use promises would be to write it like this:

...
}).then(componentLoaded);
...

Since you were executing the function componentLoaded() while passing it to the promise, thus there's nothing left for the promise to execute!