Cannot chain promises using 'then'

Having trouble understanding why the 'describeDir' promise chain is not working properly. Can anyone help me figure out what I did wrong here? Everything in the code seems to run, but functions like then or finally from the promise API never get executed. Below are two of the main functions. You can find the code repository on Github at https://github.com/PhoenixContactUSA/pcworx-doc-gen

function updateDescriptor(fileloc, wsName, outdir){
  console.log('Updating descriptor file for: ' + wsName);
  return new Promise(function(resolve, reject){
    return getDescriptor(outdir).then(
      (value) => {
        let descriptorFile = value;

        var comments = getComments(fileloc);
        var variables = getVariables(fileloc);

        //wait until both are completed before continuing
        return Promise.all([comments, variables]).then((values) => {
          descriptorFile[wsName] = new Object();
          descriptorFile[wsName].comments = values[0];
          descriptorFile[wsName].variables = values[1];

          //save the file
          return saveDescriptor(descriptorFile, outdir).then((value) => {
            console.log('Completed ' + wsName + ' ' + value);
            resolve(value);
          }, (reason) => {console.log(reason)})

        }, (reason) => {
          console.log(reason);
        }

        )


      },
      (reason) => {console.log(reason)}
    )



  })

}

function describeDir(filedir, outdir){

  var files = findFilesInDir(filedir, '.XML');
  for (var k=0;k<files.length;k++){
    if ((files[k].indexOf('@HW') !== -1) || (files[k].indexOf('@LIBS') !== -1) || (files[k].indexOf('@ROOT') !== -1) || (files[k].indexOf('run') !== -1)) {
      files.splice(k,1);
    }
  }

  return Promise.each(files, function(file){
      return updateDescriptor(file, path.basename(file), outdir);
  });

}

After calling the functions here, everything seems to work correctly, but the then() function is not being called. Note that I'm using bluebird in this latest version.

docProcessor.describeDir(folder, path.join(__dirname, '..')).then((value)=> {
      console.log('docProcessor then entered: ' + value);
});

Answer №1

Initially, to verify for a rejection, attempt

docHandler.checkDirectory(directory, path.resolve(__dirname, '..'))
.then(result => console.log('docHandler then executed:', result))
.catch(error => console.error('error', error);

An issue that may arise in the checkDirectory function is the loop used to filter files containing @HW, @LIBS, @ROOT, or run in their names

During the splicing of the files array at index k, the k++ operation still runs, causing the next file to be skipped during testing

For example,

array = [a, b, c, d];
k == 1 // testing "b"
array.splice(k, 1);
now array = [a, c, d]
k++; // == 2
next iteration checks "d"

Hence, if there are two consecutive files with any of those strings, one might be unintentionally skipped - could this be the problem?

To address this, consider using the filter method instead

function checkDirectory(dir, outputDir) {
    var files = findFilesInFolder(dir, '.XML')
    .filter(file => 
        file.indexOf('@HW') === -1 && 
        file.indexOf('@LIBS') === -1 && 
        file.indexOf('@ROOT') === -1 && 
        file.indexOf('run') === -1
    );

    return Promise.each(files, file => updateDescriptor(file, path.basename(file), outputDir));
}

or a more concise version

function checkDirectory(dir, outputDir) {
    var files = findFilesInFolder(dir, '.XML')
    .filter(file => !/@HW|@LIBS|@ROOT|run/.test(file));

    return Promise.each(files, file => updateDescriptor(file, path.basename(file), outputDir));
}

Additionally, here's an optimized and modernized version of the updateDescriptor function utilizing latest ES2015+ features (with original comments preserved)

function updateDescriptor(filePath, worksheetName, outputDir) {
    console.log('Updating descriptor for: ' + worksheetName);
    return retrieveDescriptor(outputDir)
    .then(data => Promise.all([fetchComments(filePath), fetchVariables(filePath), data]))
    .then(([comments, variables, descriptorFile]) => {
        descriptorFile[worksheetName] = { comments, variables };
        return storeDescriptor(descriptorFile, outputDir)
    }).then((data) => {
        console.log('Completed ' + worksheetName + ' ' + data);
        return data;
    })
}

Note the absence of explicit error handling code since errors should propagate through

A condensed version of updateDescriptor would be

const updateDescriptor = (filePath, worksheetName, outputDir) => retrieveDescriptor(outputDir)
    .then(data => Promise.all([fetchComments(filePath), fetchVariables(filePath), data]))
    .then(([comments, variables, descriptorFile]) => 
        storeDescriptor(Object.assign(descriptorFile, { [worksheetName]: { comments, variables } }), outputDir)
    );

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Numerous objects come into view as you scroll

I found a code snippet online that animates items as they appear on scroll. However, the code only triggers animation for one item at a time. How can I modify the code to trigger the animation for all items? const observer = new IntersectionObserver(e ...

The drop-down menu keeps flickering instead of remaining open when clicked

I am facing an issue with a dropdown menu in my webpage. The menu is initially hidden, but should become visible when the list element containing it is clicked. I have written JavaScript code to add a class that changes the visibility property to visible u ...

Angular: Exploring the possibilities of condition-based click event implementation

In my component, there are two elements: 'order information' and a 'datepicker'. When clicking on the component, it will display the order information. However, I want to prevent the click event from being triggered if the user clicks ...

Issue with initializing MdTable in Vue Material when fetching data

After encountering a null error while trying to fetch remote data to initialize the MdTable component, I shared my issue here. The data is retrieved from a MySQL database as part of a Laravel 5.6 API project. Upon thorough investigation, it seems that the ...

I am attempting to implement an Express static middleware as demonstrated in this book, but I am having trouble understanding the intended purpose of the example

I'm currently studying a chapter in this book that talks about Express, specifically concerning the use of express.static to serve files. However, I'm encountering an issue where the code catches an error when no file is found. I've created ...

Please provide me with the coordinates (latitude and longitude) for that address

I am looking to integrate the Google geocoder into my website. I want to be able to input any location address and receive the latitude and longitude coordinates for that location. Are there any helpful tutorials available? For reference, I found a simila ...

Get the contents inside the window.open using Javascript

First and foremost, I want to acknowledge that I understand the likelihood of this failing due to cross-domain restrictions - just seeking confirmation on that. Here's my approach: I have a window that I open using JavaScript. Subsequently, I make an ...

What is the most secure approach for defining the file path of an HTML file within an express.js application?

In my directory setup, I have the index.js file located at: path/to/home-page/src/routes This is also where you can find the __dirname. The html file resides at: path/to/home-page/public/bootstrap/Homepage/page.html To serve the html document by relati ...

Trigger a function on q-select change using onChange event (Quasar Framework)

I'm trying to get the function to run when I change the selected value, but it's not working. How can I solve this issue? Below is the code I am using: <q-select v-model="single" :options="['def', 'abc', ...

Unexpected behavior exhibited by DOM elements

I can't seem to figure out this issue. Every time I run this loop: for ( var i=0; i < 10; i++ ) { var $items = $(balls()); console.log($items); $container.imagesLoaded(function(){ $container.append( $items ).masonry( 'app ...

HTML Elements for Displaying Undefined JSON Information

Hey there, I'm new to programming and I'm looking to display JSON data in an HTML table using jQuery. The issue I'm facing is that the output from the server shows up as 'undefined'. My goal is to have a constantly updated list of ...

An unexpected import token was encountered while using ReactJS and Babel

Every time I attempt to launch my application, an error message pops up that says: (function (exports, require, module, __filename, __dirname) { import { Row } from '../grid' SyntaxError: Unexpected token import I've experimented with vari ...

Struggling to construct a project using parcel, continually encountering issues with unsupported file types

My attempt at creating a project using parcel has hit a snag. Despite diligently following the guidelines provided in my assignment, an error message consistently appears in my terminal each time I initiate the command: parcel src/index.html The error mes ...

Is it possible to have nullable foreign keys using objectionjs/knex?

It seems like I'm facing a simple issue, but I can't quite figure out what mistake I'm making here. I have a table that displays all the different states: static get jsonSchema() { return { type: 'object', propert ...

When you try to import from another file, the method is not defined

When I attempt to import a method from another file, I am encountering an issue where it returns undefined. The structure involves 3 files with one calling the next in sequence. File1: const { methodFromFile2 } = require('./file2'); methodFromFi ...

Passing arguments inside the source attribute of an image or link tag in Node.js and

As a beginner in NodeJS, I am facing an issue with passing arguments inside links and image sources. In my template.html file, I have included various scripts and elements to create a search form. The issue arises when I try to incorporate values from the ...

Why does my useEffect consistently execute after the initial rendering, despite having specified dependencies?

const [flag, setFlag] = React.useState(false) const [username, setUsername] = React.useState('') const [password, setPassword] = React.useState('') const [errorUsername, setErrorUsername] = React.useState(true) const [er ...

Integrating tooltips on Dimple.js line charts

A simplified network-style chart has been created using Dimple's line plot as the foundation. For example, please refer to this link: http://jsfiddle.net/cc1gpt2o/ myChart.addCategoryAxis("x", "Entity"); myChart.addCategoryAxis("y", "Entity").add ...

Ways to retrieve a value within a function and update a variable

Fetching data from the firebase database = firebase.database(); var ref = database.ref('urls'); ref.on('value', gotData, errData); function errData(err){ console.log('Error!'); console.log(err); } function gotData(d ...

Enhancing Bootstrap Carousel with various effects

My exploration of the web revealed two distinct effects that can be applied to Bootstrap Carousel: Slide and Fade. I'm curious if there are any other unique effects, such as splitting the picture into small 3D boxes that rotate to change the image? ...