0

Can someone explain why callback function after loadData(symbol) is not being called? I have this function:

    function plotChart(symbol) {
        alert("symbol: " + symbol);
        var data = loadData(symbol, function(){
            console.log("data: ",data);
        });
    }

I'm expecting log.console to execute after loadData completes, but nothing gets output.

In case it matters, here is the loadData function.

    function loadData(symbol) {
    count = 0;
    quotes = [];
    $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=IBM&startDate=2020-01-01&endDate=2020-09-30", function(data) {
        data.forEach(function(item){
            var quote = {};
            quote.date   = item.id.date.substring(0,10);
            quote.open   = item.open;
            quote.high   = item.high;
            quote.low    = item.low;
            quote.close  = item.close;
            quote.volume = item.volume;
            quotes.push(quote); //put quote in array
        });
        console.log("quotes: ",quotes);  
        return quotes;
    });
}

Here the console.log successfully prints out the quotes correctly.

EDIT: Per @Aluan, I changed the code to look like this:

    function plotChart(symbol) {
        loadData(symbol).then(function(data) {
            console.log("data: ", data);
        });
    }

    function loadData(symbol) {
        quotes = [];
        $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=" +symbol +"&startDate=2020-01-01&endDate=2020-09-30") 
            .then(function (data) {
            const quotes = data.map(function(item) {
                return {
                    date: item.id.date.substring(0,10),
                    open: item.open,
                    high: item.high,
                    low : item.low,
                    close: item.close,
                    volume: item.volume
                };
            });
            console.log("quotes: ",quotes);  
            return quotes;
        });
    }

But now I'm getting error: Uncaught TypeError: Cannot read property 'then' of undefined at plotChart (moneymachine.html:120) at HTMLTableRowElement.

Line 120 is loadData(symbol).then(function(data) {

0

1 Answer 1

2

The definition of loadData is essential to understanding the reason.

Given

function loadData(symbol) {
    count = 0;
    quotes = [];
    $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=IBM&startDate=2020-01-01&endDate=2020-09-30", function (data) {
        data.forEach(function (item) {
            var quote = {};
            quote.date   = item.id.date.substring(0, 10);
            quote.open   = item.open;
            quote.high   = item.high;
            quote.low    = item.low;
            quote.close  = item.close;
            quote.volume = item.volume;
            quotes.push(quote); //put quote in array
        });
        console.log("quotes: ", quotes);  
        return quotes;
    });
}

We can see that it defines one parameter, symbol. You may pass additional arguments when calling it, but it clearly does not use them.

When you write

var data = loadData(symbol, function () {
    console.log("data: ", data);
});

The second argument is simply ignored.

Here's an example of loadData that would accept and make use of a second argument that's a callback.

function loadData(symbol, callback) {
    count = 0;
    quotes = [];
    $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=IBM&startDate=2020-01-01&endDate=2020-09-30", function(data) {
        data.forEach(function(item){
            var quote = {};
            quote.date   = item.id.date.substring(0, 10);
            quote.open   = item.open;
            quote.high   = item.high;
            quote.low    = item.low;
            quote.close  = item.close;
            quote.volume = item.volume;
            quotes.push(quote); //put quote in array
        });
        callback(data) // here
        console.log("quotes: ", quotes);  
    });
}

However, this definition of loadData is suboptimal at best. It should make use of the thenable return by jQuery's $.getJson, to make the code clearer.

function loadData(symbol) {
    return $.getJSON("http://localhost:8080/springboot-crud-rest/api/v1/quotes-between?symbol=IBM&startDate=2020-01-01&endDate=2020-09-30")
        .then(function (data) {
            const quotes = data.map(function (item) {
                return {
                    date: item.id.date.substring(0, 10),
                    ...item
                };
            });
            console.log("quotes: ", quotes);
            return quotes;
        });
}

Consumed as

loadData('something').then(function (data) {
    console.log("data: ", data);
});
Sign up to request clarification or add additional context in comments.

5 Comments

I know that the symbol argument is not being used for now. But are you saying that because it is not used, the callback function is being ignored? I do not find that deeply indented code makes it clearer. Just the opposite for me. I also don't understand what callback(data) does or why it is needed.But I will give it a try. Thank you Aluan!
I changed my code to look like yours as updated in the EDIT of the original post, but now getting a new problem.
I couldn't get your second example to work, but I did get the first one working. I understand better now. I was passing a function as an argument but failing to call that function from loadData when it was done. I had thought that would happen automatically. Only where you say callback(data), I say callback(quotes). That worked.
@user3217883 I reviewed your edit the question. When you copy the second version you've missed something. You forgot return. That's why it failed
Ah, ok I see that now. Anyway I'm keeping the first version. The second one is too hard for me to understand.

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.