Newb stuck in asynchronous black hole - Wikipedia Viewer [SOLVED]

Hi,

Total newb here, way over my head.

I’ve gone down the rabbit hole on the Wikipedia reader project here:](http://codepen.io/Arthurauthor/pen/YNpPaK).

My problem is returning the value for the variable wikiImgUrl at line 107 so that I can get the associate image for the wikipedia article (if if has one).

I’ve beeing trying for days to find a way out of this asynchronous hell hole I’ve created for myself, but can’t work it out

wikiImgUrl is currently declared globally at line 3 - which I know is useless - as this is what is grabbed at line 107 .

What I want is the value that is populated at line 87 (or 90 depending on if statement).is the one that get used at line 107.

Help much appreciated.

Why not just move your append statement to the end of your if statement?

Forked CodePen

Unless I’m missing something.

Thanks heaps for the reply @cjsheets,

When I move the append statement it returns only the last wikipedia article from the search but it does collect the right amount of images.

This is where I am stuck - I can either get the images in the right place or the wikipedia articles, but not both.

I think this is because of how many function statements I’'ve got and where everything is placed within the code, but I just can’t work a solution.

Hi @Arthurauthor

The problem you’re having is to do with how variables are scoped in JavaScript.

var is function scoped, not block scoped; what this means is that when your loop finishes, those nested ajax callbacks are going to be reading from the same url, that’s why you see it repeated when you moved the append statement inside the image callback.

Now, you need append to be inside the image callback because you need all the data before you can update the DOM. The easiest way I can think of to resolve the issue is by using the let keyword.

let is a new ES6 feature that restricts the scope of the variable to blocks as well as functions - if, else, for, while statements etc…

I also made a fork of your pen and changed it to use let, thought it would be easier than trying to explain where and what you’d need to change, I also tidied it up a bit as the indentation was making it hard for me to read :stuck_out_tongue: http://codepen.io/joesmith/pen/pRRqXr?editors=0010.

I recommend you read through and compare, I had to move a few variables around to get it to work, i.e. articleStr & articleHeaderStr are declared inside the for loop, rather than at the global scope.

I hope this helps!

2 Likes

Fantastic @joesmith100,

Thanks heaps for your solution AND the time you have taken to sort out my code in a new fork so that I could see what you meant,

As way of explanation, I got into this mess because I don’t fully understand what function does and how it works in conjunction with other functions, callbacks, passing argumetns etc. After creating the basic code required to fetch Wikipedia articles I got this idea to grab the associated image too and that’s when things got far more hectic than I thought they would (here was me thinking it would be just another simple ajax call).

I read a bazillion articles on callbacks and promise and a zillion solution ideas on StachOverflow, but couldn’t get any of them to work. I literally spent two days on this problem as I didn’t just want to take the easy option and felt I had to get my head around it as much as I could. I learnt a lot - but not that I was after.

However, I did not know about “let” and none of the articles I read mentioned it either. It isn’t been mentioned in FCC tutorials (thinking about the Variable Scope it covers) interestingly and that is the only experience I have in my fledgling code career. Probably a good reason why it isn’t (or I missed it!).

Surprisingly, I actually get what the let command is doing.

I did take your solution and experiment a little bit - in that I did not declare all the variables with let - only the ones that are effected by the scope issue. It seems to be working (I didn’t restructure my code either simply because I have got used to looking at it the way it is over the last week - I do appreciate your version though and want to get my code design to that level).

I also found it interesting how you moved the MD5 code to the top, yet it can still be reached by the function that calls it (obviously that code is a cut and paste job - I didn’t even know about MD5 prior to falling down this rabbit hole).

As I said functions and how they can be called and passed as arguments etc etc - I fell like I am still waiting for the penny to drop.

Thanks again for your help and here is my version of your solution - it’s not as glossy as I would have liked but it’s tweaking and styling I know I can do. This project has chewed up enough time and I want to move one to the next challenge.

1 Like

No worries matey, I’m glad I could help.

As a bit of a warning, because let is new, not every browser supports it; which is also why FCC have avoided it and other new features because they want to reach as many people as possible, some who might be using older browsers.

However, for this situation its perfectly fine, the only other people who will likely need to review your project are the FCC team, all of which will likely be using modern browsers, and if not, you can always enable Babel on the project (gear menu, js preprocessor) which will transpile it to older javascript and still work as expected. My fork has babel and it runs fine.

This is actually scope related as well; basic rule of thumb, code should be able to read any other code in its upper scope. Because I moved MD5 to the global scope, all of the code below it should have access to it. Functionally I didn’t have to move it, it was just to make the code more readable whilst I was figuring out what was going on :stuck_out_tongue: