1

I'm writing a twitter aggregator and I need some help on solving the error 'Uncaught ReferenceError: sqTweetData is not defined.' It looks like console is pointing me to my for loop. I have set up a partial that is compiled and loaded in #main-content using underscore js.

For Loop Code

<!-- Main Content -->
<main class="main">
    <div class="container-flex" id="main-content"></div>
</main> <!-- End Main Content -->

<!-- Current Tweet Partials -->
<script id="active-tweet-partial" type="underscore/template">
    <section class="tweetFlexItem">

    <% for (var i = 0; i < sqTweetData.length; i++) { %>
        <div class="activeTweet">
            <div class="activeTweet__avatar"><img src="<%= sqTweetData[ i ].user.profile_image_url %>"></div>
            <div class="activeTweet__wrapper">
                <div class="activeTweet__name"> <%= sqTweetData[ i ].user.name %> </div>
                <div class="activeTweet__message"><%= sqTweetData[ i ].text %></div>
            </div>
        </div>
    <% } %>

    </section>
</script>

home.js Compiling Code

var Home = (function() {

var sqTweetData = {
    user: [{
        profile_image_url : "assets/avatar.png",
        name : "@johnsnow"
    }],
    text : "Someone once said that I know nothing..."
};

console.log("this is sqTweetData", sqTweetData);

// Partials
var tweetPartial = $('#active-tweet-partial').html();
    tweetPartialCompiled = _.template( tweetPartial );

// DOM Handlers

// KICKSTART VIEW
function initHome() {

    // load main content
    $('#main-content').html(tweetPartialCompiled( sqTweetData ));

    // bind events

}
return {
    init: initHome
};

})();

The console.log on line 11 works just fine, so I'm assuming my variable object is set up correctly. There just seems to be a disconnect between the partial and the rest of the javascript.

Any thoughts?

1
  • You're trying to access a variable that doesn't exist. The variable was declared in Home not in the global window Commented Dec 9, 2015 at 3:20

1 Answer 1

1

This is a scoping issue. sqTweetData says it's undefined because it's exactly that. window["sqTweetData"] does not exist. When you declare a variable outside of a function it's inserted into the global namespace, in this case the browser window is the namespace.

Since you're declaring the variable inside of home using the var keyword, the variable will only be accessible within the Home function. So you'd have to add it as either a this.sqTweetdata and return it with the object, or add a separate getTweetData() that return the variable, or something along those lines.

Check out this answer that covers scoping very comprehensively: https://stackoverflow.com/a/500459/3629438

Yours falls under:

Advanced: Closure

var a = 1;

var six = (function() {   

  var a = 6;

  return function() {
    // JavaScript "closure" means I have access to 'a' in here,
    // because it is defined in the function in which I was defined.
    alert(a);   
  }; 
})();

EDIT:

In your case you would do something along the lines of

var Home = (function() {

// ....... //    

function getTweetData() {
   return sqTweetData;
}
return {
    init: initHome,
    get: getTweetData
};

})();
Sign up to request clarification or add additional context in comments.

3 Comments

Awesome, totally makes sense. How would I go about create a getTweetData() function to pass the data for global use?
I think tweetPartialCompiled({ sqTweetData: sqTweetData}) would be a more appropriate solution in the context of an Underscore template. Underscore mangles the template into a JavaScript function and uses with to alter the scoping rules.
@muistooshort ah you are correct, I'm not as well versed in Underscore however and was answering from a standpoint of vanilla javascript

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.