Search code examples
javascriptnode.jspromiseelectronbluebird

Promise fired before waiting for result


I'm very new to promises and my following code produces some unexpected results but I don't know why.

The Taskrunner.SyncObjects function in Main.js should wait for the filled selectedCourses variable, but instead of that it just fires instantly. This results in an empty selectedCourses variable being used.

Why is it that the TaskRuner.SyncObjects function runs before having a result?

Main.js

function StartSync(){

var a = Settings.LoadCourseList(standardOSPathUserData);
var b = a.then(function(){
    console.log("b is running");
    var selectedCourses = Settings.courseList;

    return TaskRunner.SyncObjects(selectedCourses).then(function(){
        fileSyncRunning = false;
    });
}).catch(function(error){
    console.log("StartSync Error message: " + error);
});

}

Settings.js

Settings.LoadCourseList = function(osPath){
  var pathToCourseListSettings = osPath + courseListFileName;
  return new Promise(function(resolve, reject){
            try {
                return connection.Login().then(function(){
                    return connection.GetCourseList().then(function(result){
                        var allCourses = [];
                        for(var p=0; p<=result.length-1;p++){
                          allCourses.push({courseID: result[p].courseID, courseName: result[p].courseName, selected: true});
                        }
                        courseListJSON = JSON.stringify(allCourses);
                        return courseListJSON;
                    }).then(function(courseListJSON){
                        fs.appendFileSync(pathToCourseListSettings,courseListJSON,encoding='utf8');
                        console.log("New Course settings file created and filled: " + pathToCourseListSettings);
                        return resolve();
                    });
                }).then(function(){
                    return resolve();
                });
            } catch (e) {
                console.log("FAIL courseList settingsfile creation - Error: " + e.code);
                return reject(e);
            }
  });
};

Solution

  • It appears Settings.courseList is never assigned a value in Settings.js

    You could try adding

    Settings.courseList = allCourses;
    

    on the line before

    courseListJSON = JSON.stringify(allCourses);
    

    Or better yet you could do it the promise way and resolve the promise with allCourses.

    To make the promise from Settings.LoadCourseList(standardOSPathUserData); return allCourse, change

    return connection.Login().then(function(){
        return connection.GetCourseList().then(function(result){
            var allCourses = [];
            for(var p=0; p<=result.length-1;p++){
              allCourses.push({courseID: result[p].courseID, courseName: result[p].courseName, selected: true});
            }
            courseListJSON = JSON.stringify(allCourses);
            return courseListJSON;
        }).then(function(courseListJSON){
            fs.appendFileSync(pathToCourseListSettings,courseListJSON,encoding='utf8');
            console.log("New Course settings file created and filled: " + pathToCourseListSettings);
            return resolve();
        });
    }).then(function(){
        return resolve();
    });
    

    to

    return connection.Login().then(function(){
        return connection.GetCourseList().then(function(result){
            var allCourses = [];
            for(var p=0; p<=result.length-1;p++){
              allCourses.push({courseID: result[p].courseID, courseName: result[p].courseName, selected: true});
            }
            var courseListJSON = JSON.stringify(allCourses);
            fs.appendFileSync(pathToCourseListSettings,courseListJSON,encoding='utf8');
            console.log("New Course settings file created and filled: " + pathToCourseListSettings);
            return allCourses;
        });
    });
    

    and to receive that promise result change

    var b = a.then(function(){
        console.log("b is running");
        var selectedCourses = Settings.courseList;
    

    to

    var b = a.then(function(allCourses){
        console.log("b is running");
        var selectedCourses = allCourses;