2

I am trying to use an Alpaca form within a React app:

import React, { useEffect, useRef } from "react";
import $ from "jquery";
import * as popper from "popper.js";
import * as bootstrap from "bootstrap";
import * as handlebars from "handlebars";
import alpaca from "alpaca";

var jp = require('jsonpath');

export default function Form() {
    useEffect(() => {
        $("#form").alpaca({
        });
    }, []);

    return <>
        <h2>Alpaca Form</h2>
        <div id="form"/>
    </>;
}

webpack compiles this but in the browser I see this message:

jquery__WEBPACK_IMPORTED_MODULE_1___default(...)(...).alpaca is not a function

While running "npm start", the browser error shows: ReferenceError: jQuery is not defined.

Albert Gevorgyan
  • 171
  • 3
  • 10
  • don't use `var` in new code, and generally mixing `import` and `require` doesn't seem like a good idea. why not `import jp from 'jsonpath';`? And for all that's holy, don't add jquery libraries to your react apps... – ThiefMaster Oct 25 '20 at 16:11
  • Thanks. There are some React alternatives for schema-based form generation but they don't seem to be as mature as Alpaca. I can of course include it as an external script but I have seen other people's code importing it directly to React... – Albert Gevorgyan Oct 25 '20 at 16:19

2 Answers2

0

Alpaca requires handlebars.js so you need to import it before importing alpaca.js. Can you try it and tell if this works for you?

Oussama BEN MAHMOUD
  • 1,442
  • 12
  • 19
  • I have tried this: "require('handlebars');" But it still doesn't find alpaca. I suspect my "import alpaca" statement is not correct but have no idea where to import the alpaca function from? – Albert Gevorgyan Oct 25 '20 at 08:40
  • Handlebars should be imported before alpaca because alpaca uses it for template resolving, if you don't do this, alpaca won't work, can you please update your example and show me how you imported handlebars, or can you please give me more code on how you initialized alpaca? – Oussama BEN MAHMOUD Oct 25 '20 at 09:12
  • I have updated the example. Tbh I still don't know what to import from handlebars and from alpaca? I guess using a wildcard and "alpaca" as imported names is not correct? – Albert Gevorgyan Oct 25 '20 at 09:19
  • Can you please create a simple project with your example on stackblitz? I think you have an issue regarding importing handlebars. – Oussama BEN MAHMOUD Oct 25 '20 at 14:09
  • Thanks! In the meantime, my current project is under https://gitlab.com/AlbertGevorgyan/bootreact At the moment I can only integrate Alpaca into React as an external script but this is not a good solution. – Albert Gevorgyan Oct 25 '20 at 14:30
  • Actually I am using webpack - this may be a part of the problem perhaps? – Albert Gevorgyan Oct 25 '20 at 14:32
  • I think so, the issue is with importing jquery, I think there's some kind of custom config to do in webpack, but before that you can import handlebars and alpaca using require method ( var Handlebars = require("handlebars"); var alpaca = require("alpaca"); ) with that you'll probably get a "jQuery is not defined" error. Can you try this? – Oussama BEN MAHMOUD Oct 25 '20 at 14:41
  • That is not unlikely. When I run "npm start", the stack frame seems more informative: .../bootreact/reactboot/node_modules/alpaca/dist/alpaca/bootstrap/alpaca.js:7013 7010 | }; 7011 | 7012 | > 7013 | })(jQuery); 7014 | 7015 | ///////////////////////////////////////////////////////////////////////////////////////////////////// 7016 | ///////////////////////////////////////////////////////////////////////////////////////////////////// View compiled ... – Albert Gevorgyan Oct 25 '20 at 14:51
  • The stackblitz project: https://stackblitz.com/edit/react-alpaca?file=src/App.js – Albert Gevorgyan Oct 25 '20 at 14:59
0

Looks like I have found a solution that works in a Spring Boor application. First, I create a static js script with only one function:

function alpacaForm(tag, config) {
    $(tag).alpaca(config);
}

Then I include this script in index.html, following all Alpaca dependencies:

    <!-- dependencies (jquery, handlebars and bootstrap) -->
    <script type="text/javascript" src="//code.jquery.com/jquery-1.11.1.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
    <link type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
    <script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>

    <!-- alpaca -->
    <link type="text/css" href="//cdn.jsdelivr.net/npm/alpaca@1.5.27/dist/alpaca/bootstrap/alpaca.min.css" rel="stylesheet"/>
    <script type="text/javascript" src="//cdn.jsdelivr.net/npm/alpaca@1.5.27/dist/alpaca/bootstrap/alpaca.min.js"></script>
    <script type="text/javascript" src="./js/alpacaForm.js"></script>

Then I just call alpacaForm in my React app:

export default function Form() {
    useEffect(() => {
        alpacaForm("#form", {
               "schema": {
                   ...
               },
               "options": {
                   ...
               }
           }
        );
    }, []);

    return <>
        <h2>Alpaca Form</h2>
        <div id="form"/>
    </>;
}

See the source code here: https://gitlab.com/AlbertGevorgyan/bootreact

Albert Gevorgyan
  • 171
  • 3
  • 10