Cannot read property of undefined

Cannot read property of undefined
0

#1

getQuotes().quotes said that there’s no quotes property.

Here is the JSON https://jsonbin.io/5b5cd77c7b2129536785269a

let quotesData;


 function getQuotes(){
    $.ajax({
      type: 'GET',
      url: '//api.jsonbin.io/b/5b5cd77c7b2129536785269a',
      dataType: 'json',
      success: function(jsonQuotes) {
        if (typeof jsonQuotes === 'string') {
          quotesData = JSON.parse(jsonQuotes);
          console.log(quotesData);
        }
      },
      error: function() {
        console.log('Error: ' + jsonQuotes);
      }
    });
  }


  $(document).ready(function(){
    getQuotes().quotes;  // error goes here
  })

#2

What exactly did you think this line above would do?


#3

You aren’t returning anything on success


#4

But how to return? I thought it will store it in quotesData.


#5

It does store it in quotesData, but you can not access quotesData outside of the success function. Anything you want to do with quotesData, you need to do inside the success function. You can call other functions from within it, but those calls must originate from the success function.


#6

I add return $.ajax({... but I’m still getting the same error.


#7

First of all, whenever I encounter an error like “cannot read property of undefined”, that means that some variable that I thought I knew what it was, is really something else. I would start console.logging things out. If some property or array element is not defined, then back up and figure out what is defined.

But looking at your code, I see a few problems. The URL doesn’t look right, and you don’t seem to be comprehending AJAX and now functions return data.

I can get your code to work like this:

function getQuotes() {
  $.ajax({
    type: "GET",
    url: "https://api.jsonbin.io/b/5b5cd77c7b2129536785269a",
    dataType: "json",
    success: function(jsonQuotes) {
      console.log('available in ajax CB', jsonQuotes);
    },
    error: function(err) {
      console.log("Error: " + err);
    }
  });
}

$(document).ready(function() {
  getQuotes();
});

At least now the AJAX is getting data.

Realize that if you try to return data out of that, it will not work because it is asynchronous:

function getQuotes() {
  $.ajax({
    type: "GET",
    url: "https://api.jsonbin.io/b/5b5cd77c7b2129536785269a",
    dataType: "json",
    success: function(jsonQuotes) {
      console.log('available in ajax CB', jsonQuotes);
      return jsonQuotes
    },
    error: function(err) {
      console.log("Error: " + err);
    }
  });
}

$(document).ready(function() {
  console.log('returned in body', getQuotes());
});

That value is defined inside the AJAX callback when the console.log is run in the second to last line. Reread that last sentence and if you do no understand exactly what that means, then you need to do some homework. AJAX values will be available only in their callbacks, functions called from those callback, or global variables that you know for a fact will be accessed after the time delay of the AJAX call. Again, you need to understand that.

Now, realize that the AJAX is asynchronous so you cannot access that in the body. Unless…

There are ways around that like async/await.

let quotesData;

async function getQuotes() {
  try {
    quotesData = $.ajax({
      type: "GET",
      url: "https://api.jsonbin.io/b/5b5cd77c7b2129536785269a",
      dataType: "json"
    });
  } catch (error) {
    console.error('Error:', err);
  }
}

$(document).ready(function() {
  getQuotes();
  console.log('accessing in body', quotesData);
});

You’ll need some JS polyfills - you can see how I set up this pen.

But I think a traditional callback structure is probably better for a learner. I know AJAX is confusing. Here’s a pen I wrote a while back to help with understanding async. I hope it helps. Let us know if you have any other questions. I guarantee that there is nothing you can ask that 100 other people on this forum are wondering too.