JSON codes doesn't always execute


(Scott Trager) #1

So we have a small bit of Javascript getting data out of the Top Posts to list in our sidebar. This works fine the first time the page is loaded, However, if using the “back” button in the browser, or even clicking a link to the homepage, most of the time it loads up and displays an empty box. How can I force this to load the list every time it is displayed?

<script>
$.ajax("http://OUR_IP/latest.json").then(function (result) { 
  var topics = result.topic_list.topics; 
  var myDiv1 = document.getElementById("top-post-body");
 
  for (var t = 0; t < 10; t++) {
    myDiv1.innerHTML = myDiv1.innerHTML + ("<div class='top-post-link'>" +"<a href='/t/" +topics[t].slug+"'>" + topics[t].title + "</a></div>"); 
    
  }
}); 
</script>

What is the number in the topic URL?
(Khoa Nguyen) #2

Your code only excute on first page load. You have to add a listener on hash change, …


(Scott Trager) #3

Any chance for some syntax?


(Khoa Nguyen) #4

Wrap your current code within a function and add a listener to excute that
function


(Mittineague) #5

Wouldn’t that fire as a topic page is scrolled down, new content pulled in or otherwise?
And not fire on list pages?


(Khoa Nguyen) #6

Yes. I forgot that part


(Scott Trager) #7

So I just put this around the whole thing and it will always fire?

if (“onhashchange” in window) {

//CODE HERE

}


(Khoa Nguyen) #8

Nope.
if("onhashchange" in window) detect if the browser supports the event.

This is a nice example.

function locationHashChanged() {
    if (location.hash === "#somecoolfeature") {
        somecoolfeature();
    }
}

window.onhashchange = locationHashChanged;

But

so I don’t know how to make it right.


User card backgrounds don't serve from CDN domain
(Mittineague) #9

Ideally I would like Discourse to fire a “new content loaded” event that could be used by custom JavaScript code.

I have tried using Mutation Observer. It does work - but - it can be a real memory hog.
I’ve also tried using setInterval which can work, but feels hackish.


(Scott Trager) #10

Ok so just replace “somecoolfeature();” with my own function from above? So something like:

<script>

function locationHashChanged() {
    if (location.hash === "#somecoolfeature") {

$.ajax("http://OUR_IP/latest.json").then(function (result) { 
  var topics = result.topic_list.topics; 
  var myDiv1 = document.getElementById("top-post-body");

  for (var t = 0; t < 10; t++) {
    myDiv1.innerHTML = myDiv1.innerHTML + ("<div class='top-post-link'>" +"<a href='/t/" +topics[t].slug+"'>" + topics[t].title + "</a></div>"); 

  }
}); 




   }
     }

window.onhashchange = locationHashChanged;
  </script>

???


(Robin Ward) #11

Is the sidebar visible on every page? Or only some?

(This is the kind of thing that really should be done in a plugin)


(Scott Trager) #12

We are using a plugin for the sidebar…

It displays on the front page (/category) only - we display:none’d the whole bar on the other pages.


(Khoa Nguyen) #13

No, you should remove if condition.
Why don’t you use jQuery selector in your code. I see you are using jQuery ajax


(Scott Trager) #14

I’m not sure what you mean by a Jquery selector (I know what a selector IS, but I don’t understand the relevance)


Example of functional Jquery with Discourse that doesn't require a manual reload to run?
(Khoa Nguyen) #15

You can read about it here
http://api.jquery.com/category/selectors/


(Scott Trager) #16

Yes…again, I know what a selector IS, but I don’t see the relevance… why would using selectors instead of boolean logic affect code execution when not an initial load?