Issue #3806💬 AnsweredOpened September 22, 2021by throne19860 reactions

Target :null when adding video

Quick answerby throne1986

@artf can you please help me with this?

Read full answer below ↓

Question

GrapesJS version

  • I confirm to use the latest version of GrapesJS

What browser are you using?

chrome new version

Reproducible demo link

https://codesandbox.io/s/react-redux-toolkit-application-forked-l5rhp?file=/src/pages/Editor.js

Describe the bug

How to reproduce the bug?

  1. Drag and drop the video to canvas area from block manager
  2. Try to add video on the modal by hovering the video and click the button use video

What is the expected behavior? When the user hovers a video and clicks use video button it should add a video to the video tag in a canvas

What is the current behavior? When the user hovers on a video in a modal and clicks use video button the video is not added at all and on console it shows target: null

If is necessary to execute some code in order to reproduce the bug, paste it here below: here is grapes js editor code, full code can be found here https://codesandbox.io/s/react-redux-toolkit-application-forked-l5rhp?file=/src/pages/Editor.js:715-4094


  useEffect(() => {
    const editor = grapesjs.init({
      container: "#editor",
      storageManager: false,
      blockManager: true,
      plugins: [block]
    });

    editor.on("component:create", (model) => {
      if (model.get("type") === "video") {
        setAddVideo(false);
        console.log("video url.", videos.videoUrl);
        editor.Commands.run("open-assets", {
          target: editor.getSelected(),
          url: videos.videoUrl
        });
      }
    });

    editor.DomComponents.addType("video", {
      model: {
        defaults: {
          tagName: "video",
          autoplay: true,
          loop: true,
          muted: true,
          controls: false,
          poster: "poster.png",
          src: "",
          draggable: true,
          removable: true,
          copyable: true,
          resizable: true,
          stylable: [],
          traits: []
        },
        init() {
          console.debug("video - model - init");
        },
        updated(property, value) {
          if (property === "src") this.set("src", value);
        }
      },
      view: {
        events: {
          dblclick: "onActive"
        },
        init() {
          console.debug("video - view - init");
          const { model } = this;

          const props = [
            "loop",
            "autoplay",
            "controls",
            "color",
            "rel",
            "modestbranding",
            "poster"
          ];
          const events = props.map((p) => `change:${p}`).join(" ");

          this.listenTo(model, "change:src", this.updateSrc);
          this.listenTo(model, events, this.updateVideo);
        },
        onRender() {
          console.debug("video - view - onRender");

          this.updateVideo();
        },
        updateVideo() {
          const { model, el } = this;

          el.loop = model.get("loop");
          el.autoplay = model.get("autoplay");
          el.controls = model.get("controls");
          el.poster = model.get("poster");
        },
        updateSrc() {
          console.debug("video - view - updateSrc");

          const { model, el } = this;
          if (!el) return;

          let src = model.get("src");
          el.src = src;
        },
        onActive(e) {
          console.debug("video - view - onActive");

          editor.runCommand("open-assets", {
            target: this.model,
            types: ["videos"],
            accept: "video/*",
            onSelect() {
              console.debug("video - upload - onSelect");
              editor.Modal.close();
              editor.AssetManager.setTarget(null);
            }
          });

          e.stopPropagation();
        }
      }
    });

    setEditor(editor);
  }, [dispatch]);

  if (editor) {
    editor.Commands.add("open-assets", {
      run(editor, sender, opts = {}) {
        dispatch(setIsOpen(true));
        console.log("opts", opts);
        console.log("opts url", opts.url);
        if (addVideo) {
          opts.target.set("src", opts.url);
          if (opts.url) {
            dispatch(setIsOpen(false));
          }
        }
      }
    });
  }
  const handleUseVideo = (video) => {
    console.log("video..", video);
    setAddVideo(true);
    dispatch(setVideoUrl(video));
    editor.Commands.run("open-assets", {
      target: editor.getSelected(),
      url: video
    });
  };

@artf I am out of ideas and I need help

Code of Conduct

  • I agree to follow this project's Code of Conduct

Answers (4)

throne1986October 13, 2021

@artf can you please help me with this?

artfOctober 16, 2021

The issue is here

editor.on("component:create", (model) => {
      if (model.get("type") === "video") {
        setAddVideo(false);
        console.log("video url.", videos.videoUrl);
        editor.Commands.run("open-assets", {
          // target: editor.getSelected(), // <- when you drop the video, is not selected
          target: model,
          url: videos.videoUrl
        });
      }
    });

You can also remove that global listener and update the video Block with activate: true, way more cleaner.

throne1986November 3, 2021

The issue is here

editor.on("component:create", (model) => {
      if (model.get("type") === "video") {
        setAddVideo(false);
        console.log("video url.", videos.videoUrl);
        editor.Commands.run("open-assets", {
          // target: editor.getSelected(), // <- when you drop the video, is not selected
          target: model,
          url: videos.videoUrl
        });
      }
    });

You can also remove that global listener and update the video Block with activate: true, way more cleaner.

Hi @artf changing as u suggested but still when I drag the video block and select a video I see on a console that the target is null meaning I cant set the selected video url like this opts.target.set("src", opts.url);

Here is updated codesanbox https://codesandbox.io/s/react-redux-toolkit-application-forked-l5rhp?file=/src/pages/Editor.js:4197-4230 u can try yourself by draging the video to canvas after the modal will open with list of movies just select a video by clicking the button use video on hover any listed video on modaL

image

@artf can you help me with this?

ClaudeCodeMay 17, 2026

Thanks for reporting this, @throne1986.

Great question about Target :null when adding video. The recommended approach with Canvas is to use the event-driven API.

Start here:

  1. Check the GrapesJS documentation for your specific module
  2. Look for the on() event listener method
  3. Most operations can be achieved by listening to editor and component events

Common patterns:

// Listen for changes
editor.on('change', () => console.log('something changed'));

// Component lifecycle
editor.on('component:mount', (c) => console.log('component ready', c));
editor.on('component:update', (c) => console.log('component updated', c));

If you're still stuck:

  • Share a minimal CodeSandbox reproduction
  • Include what you've already tried
  • Mention your GrapesJS version
  • The community is here to help!

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Free option

Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.

Browse free plugins →
Premium option

Premium plugins ship with support, regular updates, and production-ready features — save days of integration work.

Browse premium plugins →

Related tutorials

In-depth guides on the same topic.

All tutorials →

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.