j.kherfan j.kherfan - 8 days ago 7
Javascript Question

function returning undefined when using

i have a function that connect to MsSQL database to get some data and build a text statement , here it's :

function getActions(issue_id, callback){
var action = '';
var conn2 = new sql.Connection(config, function(err) {
if(err){
showNotification('error connecting for selecting actions for ALL issues: ' + err.message, 'danger', 'glyphicon glyphicon-tasks');
} else {
var request = new sql.Request(conn2);
request
.input('issue_id', sql.Int,issue_id)
.query('SELECT [date], [description] FROM [actions] WHERE [issue_id] = @issue_id')
.then(function(data2) {
action ='<tr>'+
'<td style="vertical-align: top;" class="bold">action:</td>'+
'<td>'+
'<table>';
data2.forEach(function(data21){
action +='<tr>'+
'<td>'+data21.date+'</td>'+
'<td>'+data21.description+'</td>'+
'</tr>';

});
action += '</table>'+
'</td>'+
'</tr>'+
'</tbody>'+
'</table>';
console.log(action);
callback(null, action);
}).catch(function(error) {
showNotification('Error on selecting actions for ALL issues:' + error.message, 'danger', 'glyphicon glyphicon-tasks');
});

}

});
}


but when i use the function in another place in my code it return undefined instead of the text statement , i make a console.log(action) before the return statement it it return the correct text ..... i did't get it why it return undefined when using the function

UPDATE when i used the function from Aruna i'm using the function like this:

for(let b=0;b<id.length;b++){
getActions(id[b],function(err, action) {
arrAction[b] = action;
});
}

Answer

As you connect and query MySQL database asynchronously, you can't expect the data returned synchronously.

You should use 'callback' to handle this.

So your code can be like this,

function getActions(issue_id, callback){
var action = '';
var conn2 = new sql.Connection(config, function(err) {
    if(err){
        showNotification('error connecting for selecting actions for ALL issues: ' + err.message, 'danger', 'glyphicon glyphicon-tasks');
    } else {
        var request = new sql.Request(conn2);
        request
        .input('issue_id', sql.Int,issue_id)
        .query('SELECT [date], [description] FROM [actions] WHERE [issue_id] = @issue_id')
        .then(function(data2) {
            action ='<tr>'+
                            '<td style="vertical-align: top;" class="bold">action:</td>'+
                            '<td>'+
                            '<table>';
            data2.forEach(function(data21){
                action +='<tr>'+
                                '<td>'+data21.date+'</td>'+
                                '<td>'+data21.description+'</td>'+
                                '</tr>';

            });
            action += '</table>'+
                            '</td>'+
                            '</tr>'+
                            '</tbody>'+
                            '</table>';
            console.log(action);
            callback(null, action);
        }).catch(function(error) {
            showNotification('Error on selecting actions for ALL issues:' + error.message, 'danger', 'glyphicon glyphicon-tasks');
        });

    }

});    
}

And you should call the same like this,

var issue_id = 12;
getActions(issue_id, function(err, action) {
   // to do
});

Also, change your for loop like this, as you called asynchronous function inside the loop, the for loop variable "b" will get changed before the response comes from the function

var arrAction = [];
for(let b=0;b<id.length;b++){
    getActions(id[b],function(err, action) {
        arrAction[arrAction.length] = action;
    });
 }