0

enter image description hereI'm wondering why this i+=1 doesn't increment the array by 1. When I click on the button the entire array length is shown. Can someone advise me what I'm doing wrong. I'm trying to load JSON data from WP related to posts with a certain category. This category I'm loading (http://localhost:8888/wordpress/wp-json/wp/v2/photos?categories=12) has 2 posts total. When I console.log postsData.length, I get the value of 2. When I console log postsData I receive Object, Object Object, Object. These posts both load at the same time when the button is clicked, but I want the posts or each object to load 1 at a time. Below is the code:

var portfolioPostsBtn = document.getElementById("portfolio-posts-btn");
var portfolioPostsContainer = document.getElementById("portfolio-posts-container");

if (portfolioPostsBtn){
portfolioPostsBtn.addEventListener("click", function(){
      var ourRequest = new XMLHttpRequest();
      ourRequest.open('GET', 'http://localhost:8888/wordpress/wp-json/wp/v2/photos?categories=12');
      ourRequest.onload = function() {
        if (ourRequest.status >= 200 && ourRequest.status < 400) {
          var data = JSON.parse(ourRequest.responseText);
          //console.log(data);
          createHTML(data);

        } else {
          console.log("We connected to the server, but it returned an error.");
        }
      };

      ourRequest.onerror = function() {
        console.log("Connection error");
};

ourRequest.send();

});
}

function createHTML(postsData){
  var ourHTMLString = '';
// This for loop doesn't increment by 1
  for (var i=0; i<postsData.length; i += 1){
    console.log(postsData.length);
    ourHTMLString += '<h2>' + postsData[i].title.rendered + '</h2>';
    ourHTMLString += '<img class="gallery-test" src="' +postsData[i].acf.image + '"">'
  }
  portfolioPostsContainer.innerHTML = ourHTMLString;
}
8
  • Please console.log the postsData argument. Add it to your question. You can check if it is in fact an array with Array.isArray(postsData) Commented Apr 19, 2020 at 23:40
  • Hello Abraham I console log Array.isArray(postsData) and receive true back. I added the other info to question. Commented Apr 19, 2020 at 23:49
  • 1
    array.length is not 0 indexed. if it says 1, it is 1. Can you log the response text before parsing it? Commented Apr 19, 2020 at 23:57
  • I get the value of 2 I just double checked Commented Apr 20, 2020 at 0:02
  • I just ran your code in my console, it did increase by 1. Commented Apr 20, 2020 at 0:12

1 Answer 1

1

let me try to understand your question correctly. if you're trying to just display one single post per click. here's what i think you may try:

let portfolioPostsBtn = document.getElementById("portfolio-posts-btn");
let portfolioPostsContainer = document.getElementById("portfolio-posts-container");

// keep the payload to avoid unnecessary data requests
let postsData = [];

// using this to track click history to display the next post
let counter = 0;

/** not needed for disabling the button **/
// cycle (postsData.length) one by one starting at index 0
// for ex, if there are 3 posts, it would do 0, 1, 2, 0, 1, 2, to eons
// const incrementCounter = () => {
// counter = (counter + 1)%(postsData.length)
// };

// create post html if there is postsData
postsData.length && createHTML();

if (portfolioPostsBtn && !postsData.length){
portfolioPostsBtn.addEventListener("click", function(){
      let ourRequest = new XMLHttpRequest();
      ourRequest.open('GET', 'http://localhost:8888/wordpress/wp-json/wp/v2/photos?categories=12');
      ourRequest.onload = function() {
        if (ourRequest.status >= 200 && ourRequest.status < 400) {
          let data = JSON.parse(ourRequest.responseText);
          //console.log(data);
          postsData = data;
          createHTML();

        } else {
          console.log("We connected to the server, but it returned an error.");
        }
      };

      ourRequest.onerror = function() {
        console.log("Connection error");
};

ourRequest.send();

});
}


function disableButton () {
  // this would only work if portfolio-posts-btn is an actual button,
  // otherwise, you'll need to disable the listener and show the
  // user the btn is disabled somehow
  portfolioPostsBtn.setAttribute('disable', true);
}

function createHTML() {
  const strTemplate = `
    <h2>${postsData[counter].title.rendered}</h2>
    <img class="gallery-test" src="${postsData[counter].acf.image}">`;
  // append to the added posts
  portfolioPostsContainer.innerHTML += strTemplate;
  counter++;
  postsData.length === counter && disableButton();
}

Sign up to request clarification or add additional context in comments.

18 Comments

"var is a global variable" 👈 that is incorrect. Using const would also result in an error
just read your comment about wanting to display the objects one at a time. to do this, you'll need to let payload = [], counter = 0; 1. store the postsData payload in an array 2. create html template with postsData[counter] 3. add one to the counter 4. have a check from the btn click to see if payload.length is true, if so, dont fetch again, just create the html template
@Phil var is a globally scoped variable in Javascript, but yes const would in a for loop since it increments i, however, let would not.
the article below and tons others have pointed out the difference between using var and let inside of a for loop --- medium.com/front-end-developers/…
I never mentioned anything about using var vs let. What I'm pointing out is that your statement "var is a global variable" is incorrect. I was also incorrect in saying "var has block scope", it has closure scope.
|

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.