Semantic-ui-react: Form: Uncaught TypeError: this.element.form is not a function

Created on 7 Jul 2016  路  17Comments  路  Source: Semantic-Org/Semantic-UI-React

_Uncaught TypeError: this.element.form is not a function_ at https://github.com/TechnologyAdvice/stardust/blob/master/src/collections/Form/Form.js#L81.

Variable values at the moment of error:

this.element == $(this.refs.element)
this.element.form === undefined

I'm using stardust with webpack-dev-server and this issue occurs every time I use Form, including

<Form />
bug

Most helpful comment

@jukkah @padsbanger I've released 0.19.0 which solves the jQuery issues. I submitted https://github.com/jukkah/short-url/pull/1 to @jukkah's project so you can see what a working project should look like.

In short, do not include jQuery nor Semantic UI JS on the page. Also, do not include any config for these in your Webpack config. It is all handled by Stardust now.

If you do have jQuery on the page, you'll notice Stardust will tell you to remove it:

image

If you turn on debugging for jQuery localStorage.debug = 'stardust:jquery' you can see when and what Stardust is loading:

image

Let me know if you have any other issues.

All 17 comments

It looks like jQuery is not loaded. Is your project setup according the usage in the readme? Per the setup instructions, we still require jQuery until we are done removing it.

If you can provide project to reproduce the error after confirming the setup, I can take a look.

It looks like jQuery is not loaded.

No, shouldn't it fail with _Uncaught TypeError: $ is not a function_ if jQuery was not loaded correctly?

Is your project setup according the usage in the readme?

Yep, I think so.

And here is my project: https://github.com/jukkah/short-url

Sorry should have been more specific, SUI jQuery is responsible for adding the form function to jQuery. The error indicates SUI JS is not loaded.

I've looked through the project, on my mobile, and it looks correct. I also tested the SUI script src and it loads SUI js. I was able to find "$.fn.form =" in the JS as well, so that is correct.

We use this same setup in the doc site and our production apps, including webpack dev server, so I know it works. I'll have to try this out when I'm back to my computer to further diagnose the issue.

Perhaps @davezuko could run this project and identify any obvious issues for me?

I believe that there are two different versions of jQuery being loaded, one from the index.html file, and one from the Stardust dependency (and bundled with webpack). I introspected this by looking at jQuery on the window, which looks to be correct:

screen shot 2016-07-07 at 4 59 44 pm

However, then I took a look at the jQuery module being used within Stardust:

  refresh() {
    this.element = $(this.refs.element)
    window.stardust$ = $

screen shot 2016-07-07 at 5 00 57 pm

I confirmed this by looking at the bundle output and noticed that jQuery is indeed being bundled, so it exists twice, and only one of them is being extended, obviously. A quick and dirty solution is to add this to your webpack configuration:

  externals: {
    jquery: 'jQuery',
  }

This will tell webpack to use the jQuery that you've loaded from the browser. That should get you moving for now, but we really need to tweak the install guide to account for this.

Thanks much David. I would call it a bug that we are bundling jQuery with Stardust. I think we should consider updating the build config to use an external jQuery. This will not only make our bundles much smaller, but it will also allow users to choose their own version and build of jQuery.

If so, I would add some logic to the root stardust export that throws a huge warning at the user telling them that they need to include jQuery on their own (until we remove it, of course). That way users don't boot up the app without reading through all the instructions and scratch their heads about _why_ jQuery isn't included.

Stardust will have to be updated accordingly, if this is the case, since it relies on local jquery imports, and unless you're going to require people to _also_ bundle semantic jquery extensions (rather than use it from a cdn), then the only sane solution is to access jQuery directly from the window. If you don't, then it becomes important for users to understand in what order the semantic extensions are loaded along with their webpacked bundle, and that's too big of a burden to get up and running.

It's kind of a damned if you do damned if you don't situation, honestly; i.e., requiring jQuery to be on the window makes webpack configuration more complex for first-time users, and the inverse of requiring jQuery to be installed as an npm dependency means users must figure out how to get the semantic extensions loaded correctly.

These are all good points. Considering:

  1. jQuery will isn't far from removed
  2. Semantic 2.0 only works with jQuery 2.x
  3. Build updates / complications required to "unbundle" it

Perhaps we instead embrace bundling for a short time. Then we only need to update the README.md. We _could_ technically also do a check to see if jQuery exists on the window, if so, use that one.

Actually, I think bundling jQuery with Stardust might make even more sense. Once it is removed, there will be no refactors necessary for users, it is just that the library will no longer include jQuery.

This assumes user's are not likely to be using jQuery with React anyway.

@levithomason What about refactoring all import $ from 'jquery' to:

import $ from 'internal/jquery'

// internal/jquery.js
import jQuery from 'jquery'

export default window.$ || jQuery

Exactly what I'm thinking, except window.jQuery to be safe.

While you're at it, there's probably a test you could do to verify that semantic jquery was loaded, and, if not, throw the user a nice error/warning. This all just being for usability pre-jQuery-removal-enlightenment.

Aye. I'm thinking since we also need a specific version of SUI jQuery, we bundle it the same way as jQuery. Including the conditional check to see if it was already loaded. We can check for the SUI plugins we need on jQuery.

Hi guys, I am having the excatly same problem with Progress component, I am getting

Progress.js:83Uncaught TypeError: this.element.progress is not a function

None of the solutions that you have provided works for me ( apart from manually adding jquery and semantic.js via script tag in index.html)

Here is my webpack config:

var path = require('path');
var webpack = require('webpack');

module.exports = {
  devtool: 'source-map',
  entry: [
    'webpack-dev-server/client?http://localhost:1337/',
    'webpack/hot/only-dev-server',
    './src/js/app'
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.js',
    publicPath: '/dist/'
  },
  module: {
    loaders: [{
      test: /\.js$/,
      loaders: ['react-hot', 'babel'],
      include: path.join(__dirname, './src/js'),
      exclude: /node_modules/
    },
    { test: /\.less$/, exclude: /node_modules/, loader: "style-loader!css-loader!autoprefixer-loader!less-loader"},
    { test: /\.css$/,  loader: 'style-loader!css-loader!autoprefixer-loader'},
    {test: /\.jpe?g$|\.gif$|\.png$|\.ico$/, loader: 'url-loader?limit=100000'},
    {test: /\.eot|\.ttf|\.svg|\.woff2?/, loader: 'url-loader'}
    ]
  },
  plugins: [
      new webpack.optimize.OccurenceOrderPlugin(),
      new webpack.HotModuleReplacementPlugin(),
      new webpack.NoErrorsPlugin(),
      new webpack.DefinePlugin({
          'process.env': {
              NODE_ENV: JSON.stringify('development'),
              APP_ENV: JSON.stringify('browser')
          }
      })
  ],
  externals: {
    jquery: 'jQuery',
  }
};

Am i shimming/exposing jQuery good ? Any other possible fixes for that ?

@padsbanger I'm currently working on this against the example repo provided by @jukkah above. Hope to have a fix up here soon.

@jukkah @padsbanger I've released 0.19.0 which solves the jQuery issues. I submitted https://github.com/jukkah/short-url/pull/1 to @jukkah's project so you can see what a working project should look like.

In short, do not include jQuery nor Semantic UI JS on the page. Also, do not include any config for these in your Webpack config. It is all handled by Stardust now.

If you do have jQuery on the page, you'll notice Stardust will tell you to remove it:

image

If you turn on debugging for jQuery localStorage.debug = 'stardust:jquery' you can see when and what Stardust is loading:

image

Let me know if you have any other issues.

Thank you Sir, it works perferctly !

Awesome! Very glad for that 馃樃 I'm working on the jQuery free progress right now. Should have that done toady as well.

Was this page helpful?
0 / 5 - 0 ratings