javascriptlaravelgrapesjs

How to add custom data with Ju99ernaut/grapesjs-tailwind plugin?


In laravel 8 app "jd-dotlogics/laravel-grapesjs": "^3" is used and https://github.com/Ju99ernaut/grapesjs-tailwind plugin is used to add custom block at grapejs editor, which looks like https://prnt.sc/cITyK6U2AKzM I need to add custom blocks based on data of our app at this area.

Reading https://github.com/Ju99ernaut/grapesjs-tailwind page I did not find any possibility to add custom blocks in sinilar way.

So in file config/laravel-grapesjs.php I replaced path to grapesjs-tailwind file :

[
    'name' => 'grapesjs-tailwind',
    'options' => [],
    'scripts' => [
        // 'https://unpkg.com/grapesjs-tailwind'
        'js/custom-grapesjs-tailwind.min.js'
        
    ]
]

I saved file as public/js/custom-grapesjs-tailwind.min.js and unpacking it try to this file manually. All these items are filled in big array like : https://prnt.sc/VihL339Z2-g1

I try to run request with axios, but I have a problem that I can not to import axios in plain js file:

    window.axios = require('axios');
    window.axios.get('pages/{page_id}/get-custom-blocks')
      .then(({data}) => {

I got error :

ReferenceError: require is not defined

With line :

import { axios } from 'axios'

I got error :

Uncaught SyntaxError: Cannot use import statement outside a module 
  1. If there is a way to use axios in public/js/custom-grapesjs-tailwind.min.js ?
  2. Are there some other similar decisions with grapesjs compatible with "jd-dotlogics/laravel-grapesjs" ?

UPDTATED BLOCK : Looking at doc https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch I do it as next :

c = retrieveGetData('/pages/4/get-custom-blocks', {})
  .then(data => {
    console.log('retrieveGetData data::')
    console.log(data); // JSON data parsed by `data.json()` call
  });

...

async function retrieveGetData(url = '', data = {}) {
  const response = await fetch(url, data = {}, {
    method: 'GET', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, *same-origin, omit
    headers: {
      'Content-Type': 'application/json'
    },
    redirect: 'follow', // manual, *follow, error
    referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    body: JSON.stringify(data) // body data type must match "Content-Type" header
  });


  let retArray = response.json()
  console.log('retArray::')
  console.log(retArray)

  console.log('retrieveGetData retArray.customBlocks::')
  console.log(retArray.customBlocks)

  console.log('retrieveGetData retArray.Promise::')
  console.log(retArray.Promise)
  console.log('retrieveGetData retArray.PromiseResult::')
  console.log(retArray.PromiseResult)
  console.log('retrieveGetData retArray.PromiseResult.customBlocks::')
  console.log(retArray.PromiseResult.customBlocks)

  return retArray.customBlocks; 
}

In browser's console I see that I got returned data : https://prnt.sc/2llG-UG8fnRD

I expected with response.json() to get valid array of data, but looks like my request is not valid ?

UPDATED BLOCK # 2 :

I remade function retrieveGetData so that it returns response object:

async function retrieveGetData(url = '', data = {}) {
  console.log('retrieveGetData url::')
  console.log(url)

  const response = await fetch(url, data = {}, {
    method: 'GET', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, *same-origin, omit
    headers: {
      'Content-Type': 'application/json'
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: 'follow', // manual, *follow, error
    referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    body: JSON.stringify(data) // body data type must match "Content-Type" header
  });

  return response
}

and calling this method :

retrieveGetData('/pages/4/get-custom-blocks', {})
  .then(data => {        // get data from server - got Response object
    console.log('retrieveGetData data::')
    console.log(data); 
    let json_data =data.json() // I got Promise pending object

    console.log('get-custom-blocks json_data::')
    console.log(json_data)
    let c = json_data.customBlocks // get custom data - I got undefined data

    console.log('get-custom-blocks c::')
    console.log(c)

    c.forEach((function (t) { // run circle for custom data
      e.add(t.id, {
        label: t.label,
        attributes: {class: t.class},
        content: t.content,
        category: {label: t.category, open: 'Blog' === t.category}
      })
    }))

  });

I see in browser's console : https://prnt.sc/VuYb-IyK1LNf What is wrong in my code ?

UPDATED BLOCK # 3 :

Yes, declaration of retrieveGetData has async and await calling of axios :

async function retrieveGetData(url = '', data = {}) {

  const response = await fetch(url, data = {}, {
    method: 'GET', // *GET, POST, PUT, DELETE, etc.
    ...
  });

  return response
}

and calling it :

await retrieveGetData('/pages/4/get-custom-blocks', {})
  .then(data => {        // get data from server
    console.log('retrieveGetData data::')
    console.log(data); // JSON data parsed by `data.json()` call
    let json_data =data.json()

    console.log('get-custom-blocks json_data::')
    console.log(json_data)
    let c = json_data.customBlocks // get custom data

    console.log('get-custom-blocks c::')
    console.log(c)

    c.forEach((function (t) { // run circle for custom data
      e.add(t.id, {
        label: t.label,
        attributes: {class: t.class},
        content: t.content,
        category: {label: t.category, open: 'Blog' === t.category}
      })
    }))

  });

But in this case I got error :

Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules (at custom-grapesjs-tailwind.min.js:504:9)

@matiaslauriti, your code in answer is not clear. I do not see where from “data” var ? What kind of code is it

retrievedData = await retrieveGetData

? Please write this block in details...

My webpack.mix.js has :

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .sourceMaps();

mix.js('resources/js/editor-modules.js', 'public/js')
    .sass('resources/sass/pages.scss', 'public/css');

mix.js('resources/js/editor-config.js', 'public/vendor/laravel-grapesjs/assets')
    .sass('resources/sass/grapesjs-editor.scss', 'public/css');

Thanks!


Solution

  • Based on your new code, the issue would be that you are missing an await:

    retrievedData = await retrieveGetData('/pages/4/get-custom-blocks', {});
    c = data.json();
    

    Remember that the function having this code must also have async defined.


    EDIT:

    So, let me update the code:

    const retrievedData = await retrieveGetData('/pages/4/get-custom-blocks', {});
    const c = data.json();
    

    What I am saying on my answer is that you need to use await, so c is not a promise that you pass (check your original question) but real data.

    So your code needs to be wrapped in an async function like this:

    async function xxxx() {
        const retrievedData = await retrieveGetData('/pages/4/get-custom-blocks', {});
        return data.json(); // Return that or store it on variable c as you did
    }