0

I have code to load data from feeds. You can check the jsfiddle here.

<div class="agenda"></div>
<div class="agenda"></div>

<script>
label = ["Tutorials", "Widgets"];
for (m = 0; m < label.length; m++) {
    function listEvents(json) {
        var feed = json.feed;
        for (var i = 0; i < 10; i++) {
            var entry = json.feed.entry[i];
            var posttitle = entry.title.$t;

            //Style
            if (i == 0) {
                x = "<span style='color:red'>Style 1 + Label 1</span><p>" + posttitle + "</p>";
                p = "<span style='color:red'>Style 2 + Label 2</span><h4>" + posttitle + "</h4><p>";
            }
            if (i == 1) {
                y = "<p>" + posttitle + "</p>";
                g = "<h4>" + posttitle + "</h4></p>";
            }
        }

        style = [x + y, p + g];
        for (m = 0; m < style.length; m++) {
            document.getElementsByClassName("agenda")[m].innerHTML = style[m];
        }

    }

    document.write("<script src=\"http://www.allbloggertricks.com/feeds/posts/default/-/" + label[m] + "?orderby=published&alt=json-in-script&callback=listEvents\"><\/script>");
}
</script>

I use For loop to load data from 2 Labels (Tutorials, Widgets).

For each Label, I want it uses each style (normal and bold as example in jsfiddle). But I don't know why it load data from only Label.

I need your help. Thanks for all suggestion.

Bucket
  • 7,415
  • 9
  • 35
  • 45
Hai Tien
  • 2,929
  • 7
  • 36
  • 55
  • 2
    You're currently doing the JSONP call synchronously, but when that is not possible you are going to run into [problems with the iteration variable](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) (and you need to create different named global functions) – Bergi Oct 16 '13 at 13:10
  • 1
    @Bergi: Wow, I totally missed that it was synchronous when done this way. Eewww... :-) – T.J. Crowder Oct 16 '13 at 13:37

1 Answers1

6

There are several problems here.

Function declaration within control structure

Function declarations (what you have there for your listEvents function) are invalid inside any control structure. They must appear at global scope or at the top level of function scope, not within a loop, a conditional, etc. Some engines tolerate them within those structures, guessing at what you mean, but others are more strict.

Function expressions, on the other hand, can appear anywhere any expression can appear. (It's still usually best not to put them in loops.)

You can tell the difference between a function declaration and a function expression quite simply: If you're immediately using the value of the construct, it's an expression.

Function declaration:

function foo() { /* ... */ }

Function expressions:

var f = function() { /* ... */ };
var nf = function foo() { /* ... */ }; // Avoid this on old versions of IE
doSomething(function() { /* ... */ });

Reusing the same function name

Your code is trying to set up loadEvents as a JSONP callback. You don't need to have multiple copies of loadEvents, you just need one — and because of the way JSONP works, it must be a global function.

Just ensure that the logic within loadEvents handles being called more than once, as each JSONP callback is triggered.

Overwriting m

You're overwriting the value of your m variable with the function. It's harmless the way you have it, but it's still a bad idea.

Using document.write

document.write has little-to-no place in modern web pages or web applications. Create a script node and append it to the DOM instead.

Using raw string values in URL query strings

Your code generating the script tag appends the content of the label to the query string without encoding it correctly. While that works with the specific values you have in your labels arrays now, if you change your label array values, it will break. Encode them instead, using encodeURIComponent.


Here's a minimal update:

var m, label, parent; // Declare variables!
label = ["Tutorials", "Widgets"];
parent = document.getElementsByTagName('script')[0].parentNode;
for (m = 0; m < label.length; m++) {

    var script = document.createElement('script');
    script.src = "http://www.allbloggertricks.com/feeds/posts/default/-/"
                 + encodeURIComponent(label[m])
                 + "?orderby=published&alt=json-in-script&callback=listEvents";
    parent.appendChild(script);
}

function listEvents(json) {
    var m;
    var feed = json.feed;
    for (var i = 0; i < 10; i++) {
        var entry = json.feed.entry[i];
        var posttitle = entry.title.$t;

        //Style
        if (i == 0) {
            x = "<span style='color:red'>Style 1 + Label 1</span><p>" + posttitle + "</p>";
            p = "<span style='color:red'>Style 2 + Label 2</span><h4>" + posttitle + "</h4><p>";
        }
        if (i == 1) {
            y = "<p>" + posttitle + "</p>";
            g = "<h4>" + posttitle + "</h4></p>";
        }
    }

    style = [x + y, p + g];
    for (m = 0; m < style.length; m++) {
        document.getElementsByClassName("agenda")[m].innerHTML = style[m];
    }

}

Re your comment below:

But it still load only data from one "Label". I want with each style, it load a Label. Style1(normal text) load Label1(Tutorial), style2(bold text) load Label2(Widgets).

That's because your loadEvents overwrites the content of the agenda elements. Rather than having the agenda elements in the markup, you'd probably be better off adding them dynamically to some container. For instance:

<div id="agendas"></div>

Then change this:

for (m = 0; m < style.length; m++) {
    document.getElementsByClassName("agenda")[m].innerHTML = style[m];
}

to this:

var agendas = document.getElementById("agendas");
for (m = 0; m < style.length; m++) {
    var agenda = document.createElement('div');
    agenda.className = "agenda"; // If you still need this for anything
    agenda.innerHTML = style[m];
    agendas.appendChild(agenda);
}

I recommend doing some reading on the DOM, and probably using a good library to make this stuff easier — jQuery, YUI, Closure, or any of several others.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • But with my problem, how is it solved? Thanks. Actually, It's my hard problem. – Hai Tien Oct 16 '13 at 13:13
  • 1
    @happi: See the update above. I can't guarantee I caught all of the undeclared variables, and you'll have to check the logic in `loadEvents` to make sure it works properly when used more than once, but that should take you the right direction. – T.J. Crowder Oct 16 '13 at 13:13
  • T.J. Crowde: I'm updating. Thanks for help. – Hai Tien Oct 16 '13 at 13:14
  • 1
    @happi: I found another couple of issues and called them out. Hope this helps. – T.J. Crowder Oct 16 '13 at 13:17
  • But it still load only data from one "Label". I want with each style, it load a Label. Style1(normal text) load Label1(Tutorial), style2(bold text) load Label2(Widgets). It's actual my issue need solved. You can help me for this issue one more again? Thanks @T.J.Crowder. – Hai Tien Oct 16 '13 at 13:27
  • 1
    @happi: That's because your `loadEvents` overwrites the content of the `agenda` elements. You should be able to figure out how to add new agenda elements on-the-fly instead. – T.J. Crowder Oct 16 '13 at 13:35
  • Please help me one more again. I am not good at all and I tried more and more, but it cannot be solved. Thanks @T.J.Crowder much. – Hai Tien Oct 16 '13 at 13:39
  • 1
    @happi: I've added an update that should help you get going the right way. – T.J. Crowder Oct 16 '13 at 13:48
  • @T.J.Crowder: You have tried to help me much. Thanks you so much. But, problem is not still solved. You can see : https://lh3.googleusercontent.com/-yMR8Q5v8oWg/Ul6cvnC1oLI/AAAAAAAAGsI/kLi8FQqiXeg/w788-h526-no/help.png. Please update your answer to finish this question. Thanks again. – Hai Tien Oct 16 '13 at 14:05
  • 1
    @happi: You're welcome. The question was answered a long time ago, it's just that you keep running into new issues with your code. I'm sorry, but I have to step away and let you take ownership of fully debugging your code yourself. The above should be more than enough to get you headed the right way. Good luck, – T.J. Crowder Oct 16 '13 at 14:13
  • @Crowder: I understand. But to me, it's actual hard. I know you have spent more time for my issue. Thanks Crowder. Have nice a day. :) – Hai Tien Oct 16 '13 at 14:20