Exploring Pg-promise: the power of chaining conditional queries

I am currently working on figuring out the best approach for chaining conditional queries in my project.

Let me break down my scenario using some pseudo-code:

We first need to check if an item exists;
  if it doesn't:
    respond with a status of 404;
  if it does:
    then we check if the current user is the owner of the item;
      if they are not:
        redirect them to another page;
      if they are:
        fetch the details of the item and display the page;

Initially, I thought about using tasks to maintain the same connection. However, due to the various possible outcomes, I am facing challenges in effectively handling promises:

db.task(t => {
  return t.items.exists(itemId)
    .then(exists => {
      if (!exists) { // item does not exist
        // handle 404 response here
      }

      return t.items.isOwner(itemId, userId)
        .then(isOwner => {
          if (!isOwner) {
            // redirect to another page
          }

          return t.items.getById(itemId);
        })
    })
})
.then(data => {
  // Process and render data
})
.catch(console.error); // Handle unexpected errors

In case I attempt to redirect to a 404 page, the promise will still be resolved afterwards. Another alternative would involve:

if (!exists) { // item does not exist
  return Promise.reject('404');
}

...

.then(data => {
  // Successfully process and render data
}, reason => {
  // Conditions were not met as expected
})

This 'works', however, it captures both errors and unmet conditions. I am aiming for a more specific handler dedicated to unmet conditions.

Another idea I considered is:

var p = db.task(t => {
  return t.items.exists(itemId)
    .then(exists => {
      if (!exists) { // item does not exist
        // Resolve p (and break promise chain) by
        // calling something like p.resolve(() => {
        //   return res.redirect...
        // });
      }

      return t.items.isOwner(itemId, userId);
    })
    .then(isOwner => {
      if (!isOwner) {
        // Resolve p and redirect to another page
      }

      return t.items.getById(itemId);
    })
    .then(item => {
      // Everything is fine, resolve with a handler to show the page
    });
})
.then(action => {
  action();
})
.catch(console.error); // Handle unexpected errors

However, I am unsure how to resolve p. Calling Promise.resolve(...) within a nested promise resolves the subsequent promise before reaching p's then.

What is the recommended practice for chaining conditional queries and managing multiple outcomes in pg-promise while maintaining performance efficiency?

Answer №1

The primary concern raised by the author pertains to the utilization of promises rather than any specific issues with pg-promise.

db.task('simple-task', async t => {
    if (await t.items.exists(itemId)) {
        // return a 404 status;
    } else {
        if (await t.items.isOwner(itemId, userId)) {
            // redirect to another page
        } else {
            return t.items.getById(itemId); // retrieve the data
        }
    }
})
    .then(data => {
        if (data) {
            // Data successfully returned from task;
            // Display/render the data;
        }
    })
    .catch(console.error); // handle unexpected errors

Answer №2

Let's test this out and see how it goes.

In order for this to work, the item must go through each promise until it reaches either the final then block or the catch block.

// Start with the First Condition
const input = 'test input'
Promise.resolve({ item: input })



  // Repeat this process for various conditions on `item.item` and adjust `X`
  /* REPEAT START */
  .then(data => {
    if (data.hitCondition != null && data.hitCondition !== '') {
      return data;
    }

    if (conditionX(data)) {
      return Object.assign({}, data, { 
        hitCondition: 'conditionX'
      });
    }

    return data;
  })
  /* REPEAT END */




  ...



  
  .then(result => {
    const { item, hitCondition } = result
    if (hitCondition != null && hitCondition !== '') {
      // at least one condition is satisfied
      // inspect hitCondition to identify which condition was met
    } else {
      // none of the conditions were fulfilled
    }
  })
  .catch(error => {
    // An error occurred somewhere along the way
    console.error(error);
  });

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

Gather input from a form and store it in an Object upon submission

I am facing a challenge as I do not have much experience with object-oriented JavaScript. My goal is to have a form submit details such as the first and last name to an object that I've created. Here is the object I have: function Person(firstName, ...

JavaScript escape sequences are used to represent characters that are

Is there a way to pass a variable to another function in this scenario? I am inserting a textarea using JavaScript with single quotes, but when the function myFunction(abc123) is called, it appears like this, whereas it should look like myFunction('ab ...

ActiveX cannot be executed from the server

My MFC activeX control works fine when run from disk, but I encounter errors when hosting it on a server. Client: Windows 7 machine Server: Ubuntu running Apache Below is the HTML code along with the encountered errors. Any advice would be much ap ...

Utilizing Universal Windows Platform: Creating Unique Custom Triggers for Background Tasks

I am attempting to create a custom trigger called setTrigger for a background task using javascript. Initially, I believed that utilizing the contentChanged Method would be the solution... taskBuilder.setTrigger(new Windows.ApplicationModel.DataTransfer. ...

Maintaining the current image while awaiting the completion of the new image update

I have successfully implemented a script using setInterval along with the jQuery load function to periodically update an image tag. var refresh_days = setInterval(function() { $('#box_name').load("dynamic.php");}, 1000 ); While this setup wo ...

React TypeScript with ForwardRef feature is causing an error: Property 'ref' is not found in type 'IntrinsicAttributes'

After spending a considerable amount of time grappling with typings and forwardRefs in React and TypeScript, I am really hoping someone can help clarify things for me. I am currently working on a DataList component that consists of three main parts: A Co ...

The process of showcasing angularjs ng-repeat with a JSON object

I'm attempting to search for product results using AngularJS. I have retrieved a JSON object with my results, an example of which is shown below: [{"store_id":"17","user_id":"29","company_name":"Liquor R Us","company_type":"Alcohol", "phone":"(303) 5 ...

Is it possible in NodeJS to convert a GET request into a POST request?

Can you convert a GET request into a POST request in nodeJS? For instance: Let's say we have an incoming GET request for '/reset' We want to send a POST request to '/clear' with an id Is it feasible to achieve this after identif ...

Automate table column width adjustments in HTML using Selenium WebDriver

As of now, I am working on automating the process of increasing the width of an HTML table column using Selenium WebDriver. I discovered that I can retrieve the coordinates of x and y by using findElement(By.cssSelector("<Css locator>").getLocation( ...

After an asynchronous query using Mongoose in an Express route, I am unable to make any changes to the variable. It remains unchanged

I am facing an issue with modifying an empty array let last_activity = [] based on the result of a Mongoose query within an Express route. For troubleshooting purposes, I am currently trying to change it to [1, 2, 3]. Despite attempting different approache ...

Despite reaching a video readystate of 4 in HTML5, the video still hangs and does not play smoothly

Using html5, I am currently working with video and audio. I have encountered an issue where sometimes the video hangs even after its readyState === 4. The cause of this problem is unclear to me. I aim for a solution where if the video's readyState = ...

Concealing a division element if there is no content inside of it

As a newcomer to jQuery, I am experimenting with setting up a code that hides a div when the 'innerHTML' is null. However, my attempt using the code below is not working. Can anyone point out where I might be going wrong? if (($("#php-errors").h ...

What is the best way to offer compressed files on a webpage for easy extraction by a function and integration with a library?

In the process of creating an application using threejs, I have made sure to optimize my 3D models effectively. However, even after this optimization, the total size of all the models combined still amounts to a significant number like 100-150 Mb without i ...

What is the process of programmatically sorting a column in a Material UI DataGrid?

Hey there! I'm currently working on a DataGrid that has a column with a custom header, specifically a Select option. My goal is to have the column sorted in descending order every time a user selects an option from the dropdown menu. renderHeader: (pa ...

Content will adjust to the screen size after a specific re-sizing

When the width is under 1024, I want the body of the page to scale to fit the user's screen without a scrollbar. My goal is to adjust the entire body so that it fits within the browser window without a scrollbar when the width is under 1024. I attempt ...

What is the most effective method for creating a default admin user in an Express/Mongoose application?

What is the most efficient method for creating a default administrator user in an express/mongoose application? ...

The gem 'remotipart' does not display any server errors in Rails 4

Currently, I have included the 'remotipart' gem in my Gemfile like this: gem 'remotipart' This is defined in my form view new.html.erb <%=form_for @user, remote: true, html: { multipart: true, class: 'user-form' } do |f| ...

Steps to create an automatic submission feature using a combobox in HTML5 and then sending the retrieved data back to the HTML file

Here is the code snippet I've been working on: <strong>Station Name</strong> <!--This portion includes a combobox using HTML5 --> <input type=text list=Stations> <datalist id=Stations> <option>Station1</opt ...

The HTTP.GET method seems to be malfunctioning

I'm having some trouble loading an image from a HTTP.GET request into my application. The picture just won't seem to display correctly. Any suggestions on what might be causing this issue? Below is the code I am using: HTML: <ion-view view- ...

Retrieving the initial entry from a JavaScript ES2015 Map

I am working with a Map structured as follows: const m = new Map(); m.set('key1', {}) . m.set('keyN' {}) The Map may contain one or multiple items. I am wondering if there is a way to retrieve the first item by index, without using m. ...