-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom UI Plugin: Cannot add property __, object is not extensible #3146
Comments
How did you add the plugin to Uppy? There is some code missing that glues it together. |
Something like this:
@Murderlon thanks for your help! |
You are not initializing Uppy correctly, see this guide: https://uppy.io/docs/react/initializing/. Could you try that first and see if the error persists? |
The error persists using both: ES6 or hooks (useUppy). |
A UI plugin's render function must return Preact elements, not React elements, I think that might be what's wrong here. If you do this at the top of your plugin file it might do the trick: /** @jsx h */
import { h } from 'preact' (and add preact as a dependency in your project.) If so we could probably detect React elements in our ui plugin code and throw a more helpful error. |
Closing this to keep the issue count maintainable. Feel free to continue the discussion here if the issue persists and we'll help. |
I keep getting this error in my next12 project trying to create this custom plugin: import { UIPlugin } from "@uppy/core";
import { h, render } from "preact";
export class TEST extends UIPlugin {
load = render;
constructor(uppy, opts) {
super(uppy, opts);
this.type = "acquirer";
this.id = this.opts.id || "TEST";
this.title = "Drag & Drop";
this.render = this.render.bind(this);
}
render(state) {
// Check if state or opts is frozen
const isStateFrozen = Object.isFrozen(state);
const isOptsFrozen = Object.isFrozen(this.opts);
const { target } = this.opts;
console.log("Is state frozen?", isStateFrozen);
console.log("Is opts frozen?", isOptsFrozen);
const dom = document.getElementsByClassName("uppy-Dashboard-inner");
console.log(dom);
return render(<div>Simple Text Rendered with Preact</div>, target);
}
install() {
const { target } = this.opts;
if (target) {
this.mount(target, this);
}
}
uninstall() {
this.unmount();
}
} |
If you make |
@Murderlon That's how I started out but I keep getting the same error Anyway, this component: import { UIPlugin } from "@uppy/core";
export class TEST extends UIPlugin {
constructor(uppy, opts) {
super(uppy, opts);
this.type = "acquirer";
this.id = this.opts.id || "TEST";
this.title = "Drag & Drop";
}
render(state) {
return <div>Simple Text Rendered with Preact</div>;
}
install() {
const { target } = this.opts;
if (target) {
this.mount(target, this);
}
}
uninstall() {
this.unmount();
}
} This is how it's being imported and used: import { TEST } from "application/handlers/uppy-plugins/GooglePickerPlugin";
const uppy = new Uppy({
id: "uppyChangeThumbnailModal",
debug: false,
autoProceed: false,
restrictions: {
maxNumberOfFiles: 1,
minNumberOfFiles: 1,
allowedFileTypes: ["image/*"],
},
locale: {
strings: {
dropPasteImport: "Drop images here, paste, %{browse} images or import from",
},
},
})
.use(Dashboard, {
trigger: ".UppyModalOpenerBtn",
inline: true,
target: ".uppy-container",
replaceTargetContent: true,
showProgressDetails: true,
height: 470,
browserBackButtonClose: true,
proudlyDisplayPoweredByUppy: false,
waitForThumbnailsBeforeUpload: true, // https://uppy.io/docs/transloadit/#waitForMetadata
})
.use(TEST, {
target: Dashboard,
companionUrl: CC_COMPANION_URL || "",
}) Gets me this error now: TypeError: Cannot add property __, object is not extensible (as it has always done) It renders the button but upon clicking on it, I get this error. I noticed the clicking triggers the render which then confused me because I thought somewhere in the code there were some state changes that required preact that I wasn't aware of, which is why I went down that rabbit hole. |
Why are you using https://uppy.io/docs/react/#example-basic-component I'm building a plugin right now and I don't see this error. So it must be something specific doing this in React or Next.js |
@Murderlon Can you actually show an example for a react plugin? Because all I found was the one Drag & drop one and that simply wraps the actual (preact) plugin imported over from a package. Not sure how to build a custom react plugin here or how I could render jsx elements.... I did take you advice and switched over to the react way of using the uppy instance. This is my component: import { UIPlugin } from "@uppy/core";
export default class TEST extends UIPlugin {
constructor(uppy, opts) {
super(uppy, opts);
this.type = "acquirer";
this.id = this.opts.id || "TEST";
}
install() {
const { target } = this.opts;
if (target) {
this.mount(target, this);
}
}
render() {
return <div>Simple TEXT</div>;
}
} And this is how I am using it: function SingleFileUploadModal(props: SingleFileUploadModalProps) {
const uppyInitObject = {
id: "uppyChangeThumbnailModal",
debug: false,
autoProceed: false,
restrictions: {
maxNumberOfFiles: 1,
minNumberOfFiles: 1,
allowedFileTypes: ["image/*"],
},
locale: {
strings: {
dropPasteImport: "Drop images here, paste, %{browse} images or import from",
},
},
};
const [uppy] = useState(() => new Uppy(uppyInitObject));
useEffect(() => {
if (!uppy.getPlugin("TEST")) {
uppy.use(TEST);
}
}, []);
return (
<div className="upload-modal-content position-relative">
<Dashboard uppy={uppy} />
</div>
);
} Really appreciate the fast replies btw, thanks for this! |
Update: I managed to get it working by building the component below import { UIPlugin } from "@uppy/core";
import { h } from "preact";
import { render } from "react-dom";
export class TEST extends UIPlugin {
constructor(uppy, opts) {
super(uppy, opts);
this.type = "acquirer";
this.id = this.opts.id || "TEST";
}
install() {
const { target } = this.opts;
if (target) {
this.mount(target, this);
}
}
render() {
return h("div", {
className: "uppy-Container",
id: this.id,
ref: (container) => {
if (container) {
this.container = container;
if (container) {
// This loads the jsx onto the container we just created...
render(<p>This is a React component rendered in a Preact environment.</p>, this.container);
}
}
},
});
}
} I am still not sure why this works but my best guess is that uppy gets it's desired preact render then I get to mess around with it as I wish (since now we got a container there and no errors are being emitted). Please chime in to validate my thoughts if possible @Murderlon |
You're right that this is confusing. I will create an issue to write a guide for it. For now, inside React you have two options.
However, writing this example I also run into the same error. I will take a look. |
I looked into it and what you're doing in your last example, where you render with React inside the plugin's render method, is the best way to go about this. Here what we're going to do:
render(state: State<M, B>, container: HTMLElement) {
return reactRender(
<p>This is a React component rendered in a Preact environment.</p>,
container,
)
}
|
Hello,
I'm trying to create a new UI plugin and whenever I'm trying to use it, by that specifying a target or add it as an option in DashboardModal, I'm getting this error:
Unhandled Rejection (TypeError): Cannot add property __, object is not extensible
I tried multiple ideas similar with ProgressBar and StatusBar but nothing workable so far. What I'm aiming is to replace progress bar in Dashboard with another content section for advanced details (ex: a table).
So far, one of my trying plugins is like this:
Note: if you're trying to add a target like '.Dashboard' or 'body' or you're using it in your React app like this, is gonna give you the mentioned error:
The text was updated successfully, but these errors were encountered: