adminjs icon indicating copy to clipboard operation
adminjs copied to clipboard

Unable to import the New action component

Open dor272 opened this issue 3 years ago • 3 comments

I'm trying to create a custom action that allows to create a new record for a resource with pre-filled values for some fields. I'm trying to do it by importing the New component and passing it a partial record:

import { useResource, ActionProps, New } from 'adminjs';
import { buildInitialRecord } from './utils';

const Wrapper = (props: ActionProps) => {
    const EnvironmentResource = useResource('Environment')!;
    const wrappedProps = {
        resource: EnvironmentResource,
        action: EnvironmentResource?.actions.find((action) => action.name === 'new')!,
        record: buildInitialRecord(props.record),
    };
    return (<New action={wrappedProps.action} resource={wrappedProps.resource} record={wrappedProps.record} />);
};

I get error on rendering:

Javascript Error
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. Check the render method of `Wrapper`.

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `Wrapper`.
    in Wrapper (created by BaseActionComponent)
    in ErrorBoundary (created by BaseActionComponent)
    in BaseActionComponent (created by RecordAction)
    in section (created by wrapper__StyledWrapper)
    in wrapper__StyledWrapper (created by Wrapper)
    in Wrapper (created by RecordAction)
    in RecordAction (created by Context.Consumer)
    in Route (created by App)
    in Switch (created by App)
    in section (created by styled.section)
    in styled.section (created by App)
    in section (created by styled.section)
    in styled.section (created by App)
    in App
    in Router (created by BrowserRouter)
    in BrowserRouter
    in Unknown
    in Provider

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `Wrapper`.
    at createFiberFromTypeAndProps (global.bundle.js:47191)
    at createFiberFromElement (global.bundle.js:47214)
    at reconcileSingleElement (global.bundle.js:37461)
    at reconcileChildFibers (global.bundle.js:37521)
    at reconcileChildren (global.bundle.js:39990)
    at mountIndeterminateComponent (global.bundle.js:40770)
    at beginWork (global.bundle.js:41824)
    at HTMLUnknownElement.callCallback (global.bundle.js:23416)
    at Object.invokeGuardedCallbackDev (global.bundle.js:23465)
    at invokeGuardedCallback (global.bundle.js:23520)

The above error occurred in the <Wrapper> component:
    in Wrapper (created by BaseActionComponent)
    in ErrorBoundary (created by BaseActionComponent)
    in BaseActionComponent (created by RecordAction)
    in section (created by wrapper__StyledWrapper)
    in wrapper__StyledWrapper (created by Wrapper)
    in Wrapper (created by RecordAction)
    in RecordAction (created by Context.Consumer)
    in Route (created by App)
    in Switch (created by App)
    in section (created by styled.section)
    in styled.section (created by App)
    in section (created by styled.section)
    in styled.section (created by App)
    in App
    in Router (created by BrowserRouter)
    in BrowserRouter
    in Unknown
    in Provider

React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.

When I try to console.log(New) before returning it it prints undefined.

Installed libraries and their versions

    "@adminjs/express": "^4.0.1",
    "@adminjs/mongoose": "^2.0.0",
    "adminjs": "^5.3.3",
    "express": "^4.17.2",
    "mongoose": "^5.13.13",

To Reproduce Code snippet provided above

Expected behavior To be able to import and use action components

Desktop (please complete the following information if relevant):

  • OS: Ubuntu 20.04
  • Browser: chrome
  • Version 90.0.4430.93

dor272 avatar Dec 23 '21 14:12 dor272

Have you tried temporarily removing your custom code from your Wrapper component and just returning a raw New component to see if it works at all?

I'd also try to import actions instead:

import { actions } from 'adminjs'

and later return <actions.new ... />

https://github.com/SoftwareBrothers/adminjs/blob/master/src/frontend/components/actions/index.ts

dziraf avatar Dec 28 '21 09:12 dziraf

Tried both, doesn't work.

dor272 avatar Jan 05 '22 10:01 dor272

I managed to import it by using the relative path to node_modules rather than importing it directly from the adminjs namespace.

import { New } from '../../../node_modules/adminjs/src/frontend/components/actions/new'

I'm unsure why this is would be a problem though. AdminJS has no issue importing other non-component files from the adminjs namespace. It also has no issue importing components from other libraries.

Due to the fragility of this import, I'm a bit reluctant to use it in my code unless there's confirmation that this component is intended to be extendable.


IMO it'd be great if AdminJS could support autofilling based on URL params for new actions. ie. something like:

http://localhost:8080/resources/User/actions/new?params.name=Bob&[email protected]

When the form loads, both the fields for name and email will then already be filled up.

es-lynn avatar May 10 '22 04:05 es-lynn

TODO: Verify if this is still an issue in version 7. If yes, all components should be additionally exported via adminjs/components or adminjs/ui namespace.

dziraf avatar Apr 18 '23 13:04 dziraf

After https://github.com/SoftwareBrothers/adminjs/pull/1520 is merged you should be able to:

import { New } from 'adminjs'

dziraf avatar Jun 27 '23 06:06 dziraf