vue-editor-js icon indicating copy to clipboard operation
vue-editor-js copied to clipboard

Image Tool: uploading failed because of incorrect response - Nuxt

Open ThomasBullock opened this issue 4 years ago • 9 comments

Have implemented vue-editor-js is nuxt as per instructions and set up config as per https://github.com/ChangJoo-Park/vue-editor-js#upload-image--110 and added a backend as per https://github.com/ChangJoo-Park/vue-editor-js-imageserver Problem is the configuration of editor image tools doesn't seem to be working. The endpoint doesnt seem to have any effect and selecting a file initiates a POST request to my current nuxt path Request URL: http://localhost:6969/admin/post/new which responds with

Image Tool: uploading failed because of incorrect response: "<!doctype html>\n<html data-n-head-ssr>\n  <head >\n    <title>future-wars-nuxt</title><meta data-n-head=\"ssr\" charset=\"utf-8\"><meta data-n-head=\"ssr\" name=\"viewport\" content=\"width=device-width, initial-scale=1\"><meta data-n-head=\"ssr\" data-hid=\"description\" name=\"description\" content=\"Nuxt frontend for Future Wars\"><link data-n-head=\"ssr\" rel=\"stylesheet\" 
etc etc .......

Inspecting the editor vis this.$refs I can see the configuration.tools.image is empty. Should this be displaying the config settings?? Screen Shot 2020-01-12 at 4 20 46 pm

Here is my component for reference

<template>
  <div class="page">
    <m-form title="New Post">
      <m-input name="title" label="title" v-model="title" />
      <m-input name="slug" label="slug" v-model="slug" />
      <m-input name="tags" label="tags" v-model="tags" />
      <client-only>
        <datepicker placeholder="Select Date" v-model="date"></datepicker>
      </client-only>
      <h1 style="text-align: center;">Editor.js on Nuxt.js</h1>
      <m-button variant="primary" @click="save">Save</m-button>
      <m-button variant="primary" @click="clear">Clear</m-button>
      <m-button variant="secondary" @click="log">Log</m-button>
      <select @change="handleTypeChange">
        <option v-for="type in types" :key="type" :value="type">
          {{
          type
          }}
        </option>
      </select>
      <hr />
      <client-only>
        <editor
          autofocus
          :config="config"
          @change="updateEditor"
          @ready="editorReady"
          :init-data="initData"
          ref="editor"
        />
      </client-only>
    </m-form>
  </div>
</template>

<script>
import Slugify from 'slugify';
import { postTypes } from '~/constants';
import { mapGetters, mapActions } from 'vuex';
import { editorBlocksInit } from '~/constants'; 

export default {
  name: 'NewBlogPost',
  middleware: ['check-auth', 'auth', 'is-admin'], 
  data() {
    return {
      title: 'Meh Blog',
      tags: 'Stenk',
      postType: postTypes[0],
      date: new Date(),
      initData: {
        blocks: editorBlocksInit
      },
      author: null,
      config: {
        image: {
          // Like in https://github.com/editor-js/image#config-params
          endpoints: {
            byFile: 'http://localhost:2020/api/image',
            // byUrl: 'http://localhost:8090/image-by-url',
          },
          field: 'image',
          types: 'image/*',
          // Cant get this to work either
          // uploader: {
          //   uploadByFile: this.uploadByFile
          // }
        },
      }
    };
  },
  computed: {
    ...mapGetters('auth', ['getUser']),
    slug() {
      return Slugify(this.title).toLowerCase();
    },
    types() {
      return postTypes;
    }
  },
  methods: {
    ...mapActions('posts', ['create']),
    editorReady() {
      console.log('We is ready!!!!!!');
    },
    updateEditor() {
      console.log('change', this.$refs);
      this.$refs.editor.editor.save().then(outputData => {
        console.log(outputData);
        this.initData.blocks = outputData.blocks;
        this.initData.timeStamp = outputData.time;
        this.initData.version = !this.initData.version
          ? outputData.version
          : this.initData.version;
      });
    },
    save() {
      const createdPost = {
        title: this.title,
        slug: this.slug,
        tags: this.tags,
        isLive: false,
        postType: this.postType,
        author: this.getUser._id,
        content: JSON.stringify(this.initData)
      };

      this.create({ createdPost }).then(res => {
        console.log(res);
        this.$router.push(`/admin/post/`);
      });
    },
    clear() {
      console.log(this);
      this.$refs.editor.editor.clear();
    },
    log() {
      console.log(this.$refs);
    },
    handleTypeChange(e) {
      console.log(e);
      this.postType = e.target.value;
    },
    uploadByFile(file) {
      console.log('we wil upload ' + process.env.cloudinaryName)
      return this.$store.dispatch('posts/uploadImage', file)
    }
  }
};
</script>

<style></style>

I'd ultimately like to use the uploader config prop to call a vuex action in uploadByFile but nothing in config seems to be having effect at the moment??

ThomasBullock avatar Jan 12 '20 09:01 ThomasBullock

The problem is that editor sends request to the current url instead of localhost:2020 as specified in the config. Can't figure out why.

Loskir avatar Jan 14 '20 19:01 Loskir

The problem is that editor sends request to the current url instead of localhost:2020 as specified in the config.

Thanks for looking.

Any chance this could be a problem with nuxt config / proxies? FWIW here's the nuxt.config.js

export default {
  mode: 'universal',
  /*
   ** Headers of the page
   */
  head: {
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      {
        hid: 'description',
        name: 'description',
        content: process.env.npm_package_description || ''
      }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
  },
  /*
   ** Customize the progress-bar color
   */
  loading: { color: '#fff' },
  /*
   ** Global CSS
   */
  css: ['~/assets/style/main.scss'],
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [
    '~/plugins/axios.js',
    '~/plugins/globalComponents.js',
    { src: '~/plugins/vue-editor.js', ssr: false },
    { src: '~/plugins/datePicker', ssr: false },
  ],
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [['@nuxt/typescript-build']],
  /*
   ** Nuxt.js modules
   */
  modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    ['nuxt-mq'],
    '@nuxtjs/svg-sprite'
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {
    proxy: true,
    host: 'localhost',
    port: '2020',
    prefix: '/api'
  },
  /*
   ** Build configuration
   */
  mq: {
    defaultBreakpoint: 'default',
    breakpoints: {
      ...breakpoints
    }
  },
  svgSprite: {
    // manipulate module options
  },
  proxy: {
    '/api': {
      target: 'http://localhost:2020',
      changeOrigin: true
    }
  },
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {
      if (ctx.isDev) {
        config.devtool = ctx.isClient ? 'source-map' : 'inline-source-map';
      }
    }
  },
  server: {
    port: 6969 
  },
  env: {
    cloudinaryName: process.env.CLOUDINARY_NAME,
    cloudinaryKey: process.env.CLOUDINARY_KEY, 
    cloudinarySecret: process.env.CLOUDINARY_SECRET, 
  }
};

ThomasBullock avatar Jan 18 '20 06:01 ThomasBullock

For some reason, the config object is not being set on editor.js.

ishigami avatar Feb 08 '20 12:02 ishigami

I have the same problem, but I have fresh vue.js project(not nuxt), created via vue-cli, I can't overwrite config object. Any ideas how I can solve this problem?

cogor avatar Feb 10 '20 18:02 cogor

I didn't solve this problem and eventually opted for another editor. https://tiptap.scrumpy.io/ Image handling was slightly different but managed to setup something workable.

ThomasBullock avatar Feb 20 '20 00:02 ThomasBullock

Isn't there a solution?

gbgb66 avatar Apr 09 '20 16:04 gbgb66

I am having this exact same issues. It seems this plugin never use the config for image tool.

hkmsadek avatar Jun 01 '20 09:06 hkmsadek

Hi i've the same issue and the solution is to use custom uploader right here editor.js custom uploader here's example of mine

import Image from '@editorjs/image'

export const EDITOR_TOOLS = {
    image: {
        class: Image,
        config: {
            // byFile: `http://localhost:8000/upload/image`,
            uploader : {
                async uploadByFile(file : any){

                    // prepare data
                    const data = new FormData()
                    data.append('image', file)

                    // sending data
                    const req = await fetch(`${process.env.api_url}/file/upload/image`, {
                        method: 'POST',
                        body: data
                    })

                    const res = await req.json()

                    return res
                }
            }
        }
    },
}

rizki4106 avatar Jan 08 '23 01:01 rizki4106

So, in editor.js the config uploadByFile allows to set a custom function for file upload. But the response returned by the function should be in a specified format as per the editor js documentation. Documentation link: click here

` uploadByFile(file){ // your own uploading logic here

          return {
            success: 1,
            file: {
              url: <the url you have got after uploading your file>,
              // any other image data you want to store, such as width, height, color, extension, etc
            }
          };
        });
      },`

sanket-shoshin avatar Mar 22 '24 06:03 sanket-shoshin