3

So, i'm trying to write a script that will check my various wordpress installs and see if they have any updates that are needed. I've already built a plugin that will display some JSON if you post the password to a wordpress page.

The problem, is that everytime it loops through my websites, it pulls the same exact data everytime, even tho i know it should be different!

function repeatMe( ){
var places = ["website1.com", "Website2.org", "Website3.com", "Website4.com", ];

i = typeof(i) == 'undefined' ? 0 : i + 1;

$.ajax({
  url: places[i],
  method: 'POST',
  data: { 'login' : 'password' },
  dataType: 'jsonp',
  cache: true,
  timeout: 4500,
  success: function(data) {

      $('tr#'+i+' td.lastconn').text( data.title );
      console.log(data.title);
      setTimeout(repeatMe, 5000);
    },
    error: function(){
        $('#output').html('<span style="color:red;">Error</span>');
        setTimeout(repeatMe, 5000);
    }
 });

    if (i == places.length - 1) {
        i = -1; 
    }
}

setTimeout(repeatMe, 5000);

I'm fairly new to Javascript, so forgive any egregious attempts to patch it together; I'm open to instruction.

You'll see the data.title piece. It returns it the first time correctly, and then after that, it just uses the same value every time. What am I doing wrong?

JSONP Attempt

I noticed that the only data it pulled correctly was from it's own domain. And so I used this answer: Make cross-domain ajax JSONP request with jQuery

UPDATE: JSONP is now doing the same thing that the standard was doing before. Still getting data from the local domain, but then just repeating that same data when it reaches out to any other domain. No Dice :(

Community
  • 1
  • 1
DauntlessRob
  • 765
  • 1
  • 7
  • 17
  • The URLs will be treated by default as relative to the current page's address – `website1.com` is a valid directory name as well. To refer to another domain, you need to provide at least the `//` anchor, if not more – `var places = ["//website1.com", ...];` or `["http://website1.com", ...];`. Though, you will then have to deal with the [same origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy). And, note that both CORS and JSON-P are only possible if the server offers support. You can't force cross-origin requests from the client. – Jonathan Lonowski Dec 21 '15 at 02:02

4 Answers4

0

You need to give i a value outside of the function. The way you have it now, the value of i does not persist outside of the function call and your ternary operator always sets its value to 0 because it is never defined. If you set i = -1 outside the function (-1 because of the way you have your incrementor), and then call repeatMe() then the value of i will be maintained.

var i = -1;
function repeatMe( ){
    var places = ["website1.com", "Website2.org", "Website3.com", "Website4.com", ];

    $('#output').text(places);
    i = typeof(i) == 'undefined' ? 0 : i + 1;
    console.log(i);

    $.ajax({
      url: places[i],
      method: 'POST',
      data: { 'login' : 'password' },
      dataType: 'json',
      cache: true,
      timeout: 4500,
      success: function(data) {

          $('tr#'+i+' td.lastconn').text( data.title );
          console.log(data.title);
          setTimeout(repeatMe, 5000);
        },
        error: function(){
            $('#output').html('<span style="color:red;">Error</span>');
            setTimeout(repeatMe, 5000);
        }
     });

    if (i == places.length - 1) {
        i = -1;
    }
}

setTimeout(repeatMe, 5000);
wpercy
  • 9,636
  • 4
  • 33
  • 45
  • Then how come in the console log it's outputting i as different numbers? notice in the opening i have it set to log i so i could see that. It shows up correct as I run it. I've also logged places[i] and it has the new url listed each time it runs... – DauntlessRob Dec 19 '15 at 21:46
  • 1
    And it logs the same `data.title` for each iteration? – wpercy Dec 19 '15 at 21:48
  • Yes it does. I'd think it was cache but the jquery documentation says that doesn't matter for a post. – DauntlessRob Dec 19 '15 at 21:50
  • Also, I tried adding the variable like you added and it didn't change much. – DauntlessRob Dec 19 '15 at 22:17
0

Because every time i value is the same(=0). In callback, you have to give i as parameter for your function:

setTimeout(repeatMe(i), 5000);

Or make i as global variable(outside the main function) and increase it every time you call repeatMe.

wiz6
  • 51
  • 7
  • Then how come in the console log it's outputting i as different numbers? – DauntlessRob Dec 19 '15 at 21:45
  • Ok, sorry, seems your code should work fine. Try to debug if you open browser network tab and watch every request response. Or output your i value in callback. DOes it change? – wiz6 Dec 19 '15 at 22:16
  • By "output yoru i value in callback" do you mean doing console.log(i)? because that's what I've done, and everything checks out. It's really strange. Everyone's code on here does the same thing as well, no matter who wrote it: it always returns the 1st result it pulls for every row. – DauntlessRob Dec 20 '15 at 23:19
0

I have tested below code. As you can see we set the interval on document.ready and then keep repeating the same every 3 secs. After every 3secs, we increment our array index i. If the index is 4, we reset it to 0.

<script>
$(document).ready(function () {
    setInterval(repeatMe, 3000);
});

var places = ["website1.com", "Website2.org", "Website3.com", "Website4.com"];
var i = 0;

function repeatMe() {
    postSync(places[i]);
    i = i + 1;
    if (i == places.length) {
        i = 0;
    }
}

function postSync(postTo) {
    console.log(postTo + ' ' + $.now());
    $.ajax({
        url: postTo,
        method: 'POST',
        data: { 'login' : 'password' },
        dataType: 'json',
        async: false,
        cache: false,
    timeout: 4500,     
    success: function(data) {
        $('tr#'+i+' td.lastconn').text( data.title );
        console.log(data.title);                
    },
    error: function(){
        $('#output').html('<span style="color:red;">Error</span>');              
    }});
}

Kosala W
  • 2,133
  • 1
  • 15
  • 20
  • First off, your code looks simpler than mine, I appreciate that. Second, No Dice. does the exact same thing. And Third, it was looping fine. I just had the setTimeout at the bottom. I'm assuming my extra setTimeout's in the success and error of the function are useless? – DauntlessRob Dec 19 '15 at 22:10
  • Yes. I didn't test the code. But those `setTimeOuts` inside success and error are not required. I updated my answer. – Kosala W Dec 19 '15 at 22:13
  • Alright, looking at it now, I also see a second problem. I wanted it to run each ajax query a few seconds after the other. your for statement completely breaks that. Also, i tested it out, and added console.log(i) into the success function and i just get 4 copies of the number 4. – DauntlessRob Dec 19 '15 at 22:17
  • ajax is asynchronous. So you do not need to wait. Getting 4 for all 4 ajax calls indicate they all produce the same output. The above code will definitely `post` to 4 different urls. – Kosala W Dec 19 '15 at 22:23
  • And yet it doesn't. Also, in going to be running this with a hundred sites and running it from a raspberry pi. I'd prefer to run them one at a time with an interval. – DauntlessRob Dec 19 '15 at 22:41
  • Have a look at my updated answer. I have switched off `async` and also allowed you to wait inside the loop. You should be able to see which url it is posting to now. – Kosala W Dec 19 '15 at 23:06
  • Ok. I finally managed to test the code. The issue is fixed. Have a look. – Kosala W Dec 21 '15 at 03:23
0

At least I can take some solace in the fact that none of you saw it either :)

The domain names were all "website.com" or whatever, which means they were all technically RELATIVE links! So AJAX was going to "http://myhostedsite.com/website.com" instead of "http://website.com"

I happened to be accessing a wordpress website with a plugin that doesn't care where you go, as long as you post the right login info to any page on ITS DOMAIN. Therefore, I always got the same information,and it was always a success. But it never actually reached out.

As a Sidenote: that JSONP thing is pretty important, so for anyone out there that HAPPENS to run into this strange issue, don't forget your JSONP training.

DauntlessRob
  • 765
  • 1
  • 7
  • 17