skip to Main Content

I am trying to run a function twice passing in different params for both times the function runs.

Although I think the correct params are being passed at the right time, at some point my variables are updated and I am not sure when or why.

Here is my slightly simplified js:

// randomFilter
const postContent = $('.posts');
const limit = 1;
let index = 0;
let tag;

const retrievePosts = () => {
    const protocol = document.location.protocol;
    const baseURL = 'api.tumblr.com/v2/blog/';
    const blog = 'studio-lukeharby.tumblr.com';
    if (index === 0) {
        tag = 'cubes';
    } else if (index === 1) {
        tag = 'objects';
    }
    console.log('index at start:', index);
    $.ajax({
        type: 'GET',
        url: `${protocol}//${baseURL}${blog}/posts`,
        dataType: 'jsonp',
        data: {
            api_key: sw._site.tumblrAPIKey,
            tag: tag
        },
        success: function(data){
            let randomNumber;
            randomNumber = Math.floor(Math.random() * data.response.total_posts);
            console.log(`1st api call tag: ${tag}`);
            $.ajax({
                type: 'GET',
                url: `${protocol}//${baseURL}${blog}/posts`,
                dataType: 'jsonp',
                data: {
                    api_key: sw._site.tumblrAPIKey,
                    offset: randomNumber,
                    tag: tag,
                    limit: limit
                },
                success: function(data) {
                    postContent.append(`<li><img src='${data.response.posts[0].photos[0].original_size.url}' alt='[${data.response.posts[0].tags}]' /></li>`);
                    setImgProps();
                    setWrapperProps();
                    console.log('randomNumber:', randomNumber, 'posts:', data.response.total_posts);
                    console.log(`2nd api call tag: ${tag}`);
                }
            });
        },
        error: function(error){
            pageWrapper.empty();
            pageWrapper.append('<p class="content errorInfo">Sorry there was an issue retrieving the data</p>');
            postContent.remove();
            elem.removeClass(loadingClass);
            console.log(error.statusText);
        },
        complete: function() {
        }
    });
}

const initCounter = () => {
    while (index < 2) {
        index++
        retrievePosts();
        console.log('index:', index, 'tag:', tag);
    }
};

postContent.empty();
initCounter();

I have a working example jsfiddle

In theory the function should look for posts tagged 'cubes' and check for the total posts with that tag, and then return 1 of these at random. Then it should pass through the next tag, check those total number of posts and return a random one via the offset param. So in theory a post should always be returned for each cycle.

HALP

2

Answers


  1. The problem with the code above is that tag is global in scope. So here’s what’s happening:

    1. You change the index and call your retrievePost function
    2. tag is updated and your ajax call is put on a queue to be run at a later point
    3. You change the index and call your retrievePost function
    4. tag is updated and your ajax call is put on a queue to be run at a later point
    5. Both of your ajax calls are taken out of the queue and are run with the same value of tag

    Put let tag; inside of the retrievePost function and tag should be correct, although you won’t be able to print it inside the initCounter function anymore. You could also do:

    const postContent = $('.posts');
    const limit = 1;
    let index = 0;
    let outerTag;
    
    const retrievePosts = () => {
        const protocol = document.location.protocol;
        const baseURL = 'api.tumblr.com/v2/blog/';
        const blog = 'studio-lukeharby.tumblr.com';
        let tag;
        if (index === 0) {
            tag = 'cubes';
        } else if (index === 1) {
            tag = 'objects';
        }
        outerTag = tag;
        ...
    }
    const initCounter = () => {
        while (index < 2) {
            index++
            retrievePosts();
            console.log('index:', index, 'tag:', outerTag);
        }
    };
    
    Login or Signup to reply.
  2. the problem is scope.

    tag is a global variable in your code. and when you call a function in loop with ajax, ajax function dont wait for ajax to complete and returns back.

    you first call is not completed and the second call is already made. and because tag is defined as global variable so it can be change in anywhere.

    so first you get tag = ‘cubes’
    and soon after you change tag = ‘objects’.

    the solution is to pass the tag as parameter, so if you have 100 calls, each call will have its own tag. not a common variable.

    and you should make it dynamic, like what if you have more tags say 100 then would you do it if for each tag.. i am not fixing that, but you should.

    const initCounter = () => {
        while (index <= 1) {
            index++;
           if (index === 1) {
                retrievePosts('cubes');
            } else if (index === 2) {
               retrievePosts('objects');
            }
    
            console.log('index:', index, 'tag:', tag);
        }
    };
    

    and in function add the parameter

    const retrievePosts = (tags) => {
          // remove the if block for index check
          // and change "tag" to "tags" everywhere in this function.
    }
    

    here is the result after changes:
    result after

    and here is result before
    before

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search