-3

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!

mstdmstd
  • 2,195
  • 17
  • 63
  • 140
  • 1
    `require` only exists on NodeJs... You have to use `import` or have it globally imported. I am not sure where you are using the `import`, show that file please – matiaslauriti Jun 04 '22 at 04:21
  • That is unpacked version of https://unpkg.com/grapesjs-tailwind@1.0.7/dist/grapesjs-tailwind.min.js file. Can I use it ? – mstdmstd Jun 04 '22 at 04:32
  • Are there some other tools/libraries to sent request to server from js file ? – mstdmstd Jun 06 '22 at 04:30
  • 1
    You can use native `fetch`, but I would recommend you to try find the issue and use `axios` or any library you want – matiaslauriti Jun 06 '22 at 04:45
  • Do you mean this https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch library ? I have never worked with it, so yes I would prefer axios, but I do not know how to import it... – mstdmstd Jun 06 '22 at 05:58
  • Please read UPDTATED BLOCK – mstdmstd Jun 06 '22 at 14:27
  • 1
    I have added an answer to your new block. I would also use `axios` as it is more legible and easy to setup (setup data for a request). So, if you still want to fix the original error, I would share the `mix` file you have and the file that has the `axios` import that `mix` is running (like [this](https://github.com/laravel/laravel/blob/78ad150a947f6677d9cb4e3eb9a257d312fe14c3/resources/js/bootstrap.js#L9)) – matiaslauriti Jun 06 '22 at 15:29

2 Answers2

1

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
}
matiaslauriti
  • 7,065
  • 4
  • 31
  • 43
  • Is it misspelling with retrievedData = await ... ? maybe : c= await retrieveGetData( ? – mstdmstd Jun 06 '22 at 15:59
  • 1
    you need to do `data.json()`, so you can either store them both on `c` or take my approach – matiaslauriti Jun 06 '22 at 23:49
  • Please read UPDTATED BLOCK # 2 – mstdmstd Jun 07 '22 at 04:16
  • 1
    You need to share who is consuming the `retrieveGetData`, but from what I see, you still need to do `await retrieveGetData`... it is returning a promise when you want the data itself... – matiaslauriti Jun 07 '22 at 13:22
  • If I wrote await before calling of retrieveGetData like : ``` 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 ``` I got error in console : ``` Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules (at custom-grapesjs-tailwind.min.js:504:9) ``` line 504 - that is just line with : await retrieveGetData – mstdmstd Jun 07 '22 at 13:33
  • 1
    yeah, you need to make the parent function `async` and also remove the `.then`, do as I did on the answer. But could you share your `mix` file? Check my comment on your question – matiaslauriti Jun 07 '22 at 13:36
  • Sorry, I am confused at all. Please look at UPDATED BLOCK # 3 – mstdmstd Jun 07 '22 at 13:54
  • 1
    Updated. Related to your #3 update, check [this](https://github.com/laravel/laravel/blob/78ad150a947f6677d9cb4e3eb9a257d312fe14c3/resources/js/bootstrap.js#L9), do you have something like that? Check the path too. – matiaslauriti Jun 07 '22 at 14:09
  • is xxxx wrapper function of retrieveGetData ? And do I need to call xxxx() method ? – mstdmstd Jun 07 '22 at 14:28
  • 1
    `xxxx` is the function that is triggering your code, you only shared `retrieveGetData(...).then(...)`, so I am just saying that the wrapper function should have `async` – matiaslauriti Jun 07 '22 at 19:59
0

As your original question was related to the laravel-grapesjs package. So I wrote the answer here. Copying it here for your reference.

You can add it below way -- And the axios global variable will be available in your custom-grapesjs-tailwind.min.js file

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