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

Navigation through Image Filters

Everything seems fine with my code, but when I click on the navigation links, they direct me to index.html or the landing project instead of filtering the images. How can I modify the links to properly filter the images? This is the Javascript and html co ...

.parseXML yields no results

I am struggling to interpret a response from a server that should be in XML format. While I am new to web development, I am trying to quickly grasp JavaScript for an assignment. Unfortunately, I cannot control the server. My code snippet is as follows: . ...

The error you are seeing is a result of your application code and not generated by Cypress

I attempted to test the following simple code snippet: type Website = string; it('loads examples', () => { const website: Website = 'https://www.ebay.com/'; cy.visit(website); cy.get('input[type="text"]').type(& ...

Dealing with images on my live React application

For managing static images in my react app, I have integrated cloudinary as a CDN service. Can anyone suggest a seamless way to switch between using local image folders during development and switching to the CDN URL for production efficiently? ...

Persistent hover state remains on buttons following a click event

In my current project, I am dealing with a form that has two distinct states: editing and visible. When the user clicks on an icon to edit the form, two buttons appear at the bottom - one for saving changes and one for canceling. Upon clicking either of th ...

Finding items in the database using their identification numbers

I have a scenario where I am accepting a list of IDs in my request, for example [1,2,3]. How can I use typeorm and querybuilder to retrieve only objects with these IDs from my database? I attempted the following: if(dto.customersIds){ Array.prototype. ...

The selected jQuery plugin is not functioning properly within CodeIgniter framework

I recently downloaded the jQuery Chosen plugin to use the simple "multiselect" version on my website. I followed all the necessary steps and even copied and pasted the code into CodeIgniter. Despite my experience with jQuery, I am facing an issue where the ...

Ajax loaded scripts are unable to access global variables

Index.html <script> let bar = 1; </script> This html page is being loaded multiple times on the page using AJAX: article.html <script> if (bar === 1) { // perform a task } // Error: bar is not defined </script> Bar is a simple ...

Challenges in using HAML5 Canvas for mathematical applications

Hey there! I'm currently working on utilizing the canvas element to form various shapes, but I've encountered a few challenges when it comes to the mathematical aspect. Issue 1: I need to calculate an angle that is relative to the preceding line ...

Select an option from the dropdown menu to populate the contents of the second dropdown list

The provided code dynamically populates the initial dropdown list with unique pants brands: $.each(pantsBrands, function(i){ var li = $('<li>') .appendTo(pantsList); var aaa = $('<a>') .text(pantsBra ...

Redux: The action was effectively triggered, but the state remained unformed

I'm currently working on a project to familiarize myself with Redux. I am using the Redux DevTools to monitor my two states: lists and todos. However, I am running into an issue where only todos are being displayed, despite trying various troubleshoot ...

Tips for accessing payment details from a stripe paymentElement component in a React application

Here is a basic code snippet for setting up recurring payments in Stripe: await stripe ?.confirmSetup({ elements, confirmParams: { return_url: url, }, }) After browsing through the documentation and the internet, I have two unanswere ...

Is there a way to configure my dropdown menu so that only one dropdown can be open at a time and it remains open when clicking on a <li> item?

I've been working on developing a dropdown menu that appears when clicked, rather than hovered over. I've managed to implement this functionality using JavaScript, and overall, it's working quite well. Currently, the menu shows or hides whe ...

Leveraging the Google Geocode API through HTTP GET requests

I am facing a challenge in my HTML file where I have a map and I am using HTTP get with jQuery to retrieve a device's location. However, I am struggling to plot this location on the map. I need to parse the location information and display it accurate ...

Unable to halt operation when xmlhttprequest.responseText is equal to a particular value

Currently, I am incorporating XmlHttp with Java servlets in the following manner: function btnSave_onclick(){ var xmlHttp; var responseText; if (condition){ var para= "someParamsHere"; var url = "urlHere"; if (window.XMLHttpRequest) { ...

ajax is now blocking the use of Window.location

I am facing an issue with window.location while working on an ajax request. Here is the code snippet for my ajax request: function login(){ var u = document.getElementById("username").value; var p = document.getElementById("password").value; ...

Using Angular.js to Make a $http.get Request from a Different Controller

I am utilizing an HTTP resource that provides a JSON list of top 10 entities from a database by calling it in this manner: var filter= "john"; var myApp = angular.module('myApp', []); myApp.controller('SearchController', [&apo ...

Hide jQuery dropdown when mouse moves away

I am working on designing a navigation bar with dropdown functionality. Is there a way to hide the dropdown menu when the mouse pointer leaves both the navbar menu and the dropdown itself? I have tried using hover, mouseenter, and mouseleave but due to my ...

Sending Angular Material Select Option Value for Submission

HTML: <form id="reg" name="reg" enctype="application/x-www-form-urlencoded" action="http://api.phphotspot.com/v-2/client-register" method="post"> <md-input-container class="md-block"> <label for="country">Country</label&g ...

Is there a way to prevent this React function from continually re-rendering?

I recently created a small project on Codesandbox using React. The project involves a spaceship that should move around the screen based on arrow key inputs. I have implemented a function that detects key presses, specifically arrow keys, and updates the ...