deactivating a form field using a function in Next.js

Here's the scenario: I have an input slider that needs to be disabled based on the role requirements of the logged-in user. For instance, if the input is only accessible to users with an accountant level role, then it should be disabled for those who don't have that specific role. The input will still be visible, but I want it to be disabled.

The usual approach would be something like

disabled={!loggedInUser.isAccountant}
, which usually suffices. However, there are cases where multiple roles should be able to access the input, even if the user doesn't possess all of them. For example, I might want both an accountant and an admin to access the input, but not a partner, while still keeping the field viewable.

I attempted to create a function that takes the user's document and checks if any key matches a specified role passed in. If a role-key match is found and the corresponding value is true, the user has the necessary role(s) to access the input. Unfortunately, no matter what I do, the function always returns a Promise<Pending> when inserted into the disabled prop of the component.

Below is an example of the input:

<Form.Group className={styles.boolean} controlId="isPaid">
            {/* True/False */}
            <Form.Check
              type="switch"
              id="custom-switch"
              label="Is Paid User"
              checked={formData.isPaidUser}
              onChange={(e) =>
                setFormData({
                  ...formData,
                  isPaidUser: !formData.isPaidUser,
                })
              }
              // Problem is here!
              disabled={checkRole(loggedInUser, ['isAdmin', 'isAccountant']}
            ></Form.Check>
          </Form.Group>

And here's the checkRole function:

/**
 * @description Check if the user has the role passed in the array, passing in multiple roles will check if the user has any of the roles
 * @param {Object} user - The logged in user object
 * @param {Array} roles - The roles to check against
 * @returns {Boolean} - Returns true if the user has the role, false if not
 * @example checkrole({user}, ['isAdmin'])
 * @example checkrole({user}, ['isAdmin', 'isPartner'])
 *
 * @author   Austin Howard
 * @version  1.0.1
 * @since    1.0.0
 * 
 */
export default async (user, roles) => {
  if (!user) return false;
  let hasRole = false;
  await Object.keys(user).forEach((key) => {
    console.log(`key: ${key}`);
    if (roles.includes(key)) {
      console.log(`user[key]: ${user[key]}`);
      if (user[key]) {
        console.log(`setting hasRole to true`);
        hasRole = true;
      }
    }
  });
  return hasRole;
};

I've experimented with different ways of calling the function, including setting up a self-calling async function to wrap the checkRole function. However, despite these efforts, I haven't been able to get the boolean result I need correctly.

Answer №1

This code snippet does not appear to be for an asynchronous operation, perhaps switching to a synchronous approach like the following function would be more suitable:

function checkUserRole(user, roles){
  return roles.some(role => user[role]);
}

Answer №2

After some experimentation, I managed to get this working by utilizing the useState and useEffect hooks. These are used by the form input to determine whether it should be disabled or not.

Here is how the code snippet looks:

const Form = () => {
    const [disableFormInput, setDisableFormInput] = React.useState(false); // Initial state
React.useEffect(() => {
    if (user) {
      // Set up a self-invoking function to check if the user has the required roles
      (async () => {
        setCanDelete(await checkRole(loggedInUser, ['isAdmin']));
      })();
    }
}, [user]);
...,
// The input will be disabled based on the value of disableFormInput
<input disabled={!disableFormInput} ... />  

Answer №3

After collaborating with a coworker, I have come across a more efficient solution that requires less code and is highly scalable. While my initial answer was functional, it felt a bit like a workaround. Here is an improved approach:

Instead of setting booleans for each role a user has on the front end, we can simplify the process by using Regex testing on the string value of the user's roles. For instance, if a user has roles such as "admin accountant partner" in their role field within the loggedInUser object, we can easily check if they have the required roles using Regex testing.

The updated solution is as follows:

<input disabled={!/accountant|admin|partner/.test(loggedInUser.role)} ... />

This method will significantly improve scalability compared to my initial response.

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

Display: Show view once forEach loop finishes execution

I'm facing an issue with my update query execution within a loop. Is there a way to trigger the rendering of a view once the forEach loop completes all its iterations? Here's the snippet of code: conn.query(`SELECT Id, ${sfColumn} from Lead`, ...

Update a Div automatically without causing it to scroll back to the beginning of the Div

I'm encountering an issue with a script on my website that refreshes a Div every 20 seconds. The problem is, after the refresh, it automatically scrolls to the top of the Div. I want it to remain at the last scroll position and not jump to the top. Ca ...

Error encountered in Google's Structured Data Testing Tool

<script type="application/ld+json"> {"@context" : "http://schema.org", "@type" : "LocalBusiness", "name" : "mywebsite.com", "description": "Lorem ipsum dolor sit amet", "image" : "http://mywebsite.com/image.jpg", "telephone" : "987654321", ...

After loading the ajax content, remember to include the JavaScript files

Here's the situation: I am importing some php files, one of which includes a slider that requires .js files. However, when I make an ajax call, the file is imported but the js files are not. Is this normal behavior? I attempted the following: var s ...

What is the best way to upload a file to Firebase Storage using React?

I am facing difficulty uploading a file to Firebase in order to retrieve its getDownloadURL. This is the code snippet I currently have: import React, {useState, useEffect} from 'react' import { Container, Button, Row, Col, Form, Alert } from &ap ...

JavaScript or jQuery can be used to rearrange the position of child divs within parent divs with a single action

I am facing a dilemma with 5 identical divs, each containing text and an image. My goal is to rearrange the child divs so that the text comes after the image in each article. Put simply, I want the image to be displayed above the text in all instances. Al ...

Is it possible to access JSON with a numeric key and receive undefined as a result?

I've been attempting to extract information from my JSON data, but I keep getting an undefined result. Here is a snippet of my JSON: { "1": "A", "2": "B", "3": "C", "4": "D", "5": "E", "6": "F", "key":"pair" } This i ...

Sending information (prop) from _app.js to getServerSideProps in a page on the most up-to-date version of NextJS

I have a unique custom _app.js that I created: const CustomLayout = ({ children }) => (children); const myApp = ({ Component, pageProps }) => { pageProps.url = 'another url'; return ( <CustomLayout> <Co ...

What are the steps to make a basic slider with jQuery without using plugins?

<script> const animateImages = function(){ $("#slider").animate({"left":"-=1775px"},10000,function(){ $("#slider").animate({"left":"0px"},10000); animateImages(); }); }; animateImages(); </script> I incor ...

Conversation with form component in angular2

I am currently using ng2-bootstrap-modal. For adding a sample form to the example Confirm Dialog, check out ng2-bootstrap-modal. To change the template: <div class="modal-dialog"> <div class="modal-content"> <form [formGroup]="login ...

Issue with retrieving POST body from Ajax call in Play Framework

I am currently attempting to send a POST request to my backend using JSON data. The frontend call appears like this: function register() { var user = $("#form_reg_username").val(); var pass = $("#form_reg_password").val(); var referal = $("#form_reg ...

Maintain the current application state within a modal until the subsequent click using Jquery

Due to the challenges faced with drag and drop functionality on slow mobile devices, I am considering implementing a modal approach for moving elements from one place to another. Here is how it would work: When a user clicks on an item, it is visually ma ...

Obtain the final result once all promises have been successfully resolved in a loop

Here is an array of IDs: let idsArray = [1, 2, 3, 4, 5]; How can I ensure that a promise is returned only after all calls made within the loop are completed? let deferredPromise = $q.defer(), finalResult = []; fo ...

How can I utilize the JQuery GetJSON function to retrieve HTML content from an external webpage?

Imagine you're attempting a jQuery ajax request like this: $.ajax({ ... url: http://other-website.com ... }) You probably know that due to the same-origin policy, this request will fail because the URL is for an external domain. But the ...

Working with form data in Next.js

I am a newcomer to NEXT JS and I am facing an issue with sending form data from the client to the NEXTJS API. After searching for a solution for a few days, I found some explanations but couldn't quite grasp them. I would greatly appreciate it if some ...

When the button is clicked, the image vanishes into thin

One common issue is the image disappearing when users click on the Rotate Anti-clockwise or Rotate Clockwise buttons. This can be a frustrating problem to tackle! Check out this link for more information. If you run into this issue, here are some tips: ...

Error: The NgTable in AngularJS is not defined when reloading the page

I have successfully implemented Angularjs NgTable with pagination inside a tab provided by Angularjs Material in various parts of my project. However, I am facing an issue where I am unable to reload the tables in this particular case. I am unsure of what ...

Is there a way to adjust the size of the canvas element in HTML without compromising quality or resorting to zooming?

I'm currently working on a basic modeling application for the web. The main component of my app is a canvas element that I'm trying to size correctly. However, when I set the height and width using CSS, it scales the entire canvas and compromises ...

Determine the type of a nested class within TypeScript

Utilizing nested classes in TypeScript is achieved through the following code snippet: class Parent { private secret = 'this is secret' static Child = class { public readSecret(parent: Parent) { return parent.secret } } } ...

The powerful combination of Ajax and Django creates a dynamic Like button

Encountering difficulties while trying to implement a basic like button feature. Despite following various tutorials, clicking on the Like button does not yield any action. See below: models.py class Comentario (models.Model): titulo = models.CharFie ...