0

I'm not quite sure what is going on with my code. I think that Webpack for some reason is setting the value of this to undefined I have no idea why.

The webpack file builds properly - but if I console.log(this) in my app.js I get undefined - Is there something I am missing?

this 

should refer to the window and then the Controller where I log it in setVars ?

Here is my webpack file

const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path'
const entry = [path.resolve(__dirname, 'public/js/app.js'), path.resolve(__dirname, 'public/styles/scss/main.scss')];

    module.exports = {
      entry: entry,
      output: {
        filename: 'scripts/bundle.js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/'
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
              loader: "babel-loader",

            }
          },
          {
            test: /\.css$/,
            use: [
              "style-loader", "css-loader"
             ]
          },
          {
            test: /\.scss$/,
            use: [
              MiniCssExtractPlugin.loader,
              "css-loader", "sass-loader?"
            ]
          }]},
          plugins: [
            new MiniCssExtractPlugin({
              filename: "styles/[name].css",
              chunkFilename: "[id].css"
            }),
            // new HtmlWebpackPlugin()

          ]
        }

And Babel RC

{
  "presets": ["@babel/preset-env"]
}

import axios from 'axios';

  const Controller = {

    init: async () => {
      const res = await axios.get('/api/nav.json');
      const data = res.data.items;
      Controller.createNavigationMenu(data);
      Controller.getVars()
    },

    getVars: () => {
      const navigationContainer = document.querySelectorAll('.navigation__primary-menu');
      console.log(navigationContainer, this)
    },

    createNavigationMenu: (data) => {
      console.log(data)
    }
  }

Controller.init()
console.log(this)
  • What should `this` be in your opinion? – user3637541 Jan 26 '19 at 18:19
  • It should be window , where I log it at the bottom - and then it shoudl refer to the controller when I log it in getVars @user3637541 – marcus petty Jan 26 '19 at 18:21
  • You might get some insight by reading this thread: https://stackoverflow.com/questions/38589227/why-this-is-undefined-inside-a-fat-arrow-function-definition – Keno Clayton Jan 26 '19 at 18:24
  • @marcuspetty the `console.log(this)` in the top scope won't be `window` because it's not in the global scope. You are dealing with modules here, and in CommonJs modules the `this` keyword is usually `undefined` in the *module scope*. – Bergi Jan 26 '19 at 19:40

1 Answers1

-1

In getVars this is undefined because the function you use is a lambda function (() => {...}) instead of (function() { ... }). If it was a real function the context would be the context of the function. It would never be the context of Controller as that is just an object and not a class. So you could create a real class for Controller in order to create a this context.

class Controller = {
  // ...
  getVars() {
    // ...

  }
}

On the lower part of the file: I do not know exactly what webpack does, but you should not rely on it leaving this as window. In fact you should always use window explicitly. That also increases readability as it is clear what you are referring to and it makes sure that you do not misuse this in a context in which this is defined, but not as window.

user3637541
  • 574
  • 3
  • 14
  • Webpack is a module bundler, and is quite popular in modern front-end development toolkits. https://webpack.js.org/ – Keno Clayton Jan 26 '19 at 18:29
  • I know what webpack is, I did not read the code of it's `require` implementation though... – user3637541 Jan 26 '19 at 18:30
  • No, changing the singleton object into a `class` for no good reason is not the solution here. – Bergi Jan 26 '19 at 19:38
  • Well, "for no good reason"... It defines `this`, if I understood him correctly, that is what he wants. And concerning the usage as a singleton: There are other ways to make sure, we do not instantiate multiple objects of a class. To be fair, I did not realize, it is supposed to be a singleton. Still, why do you think it is not a good idea, here? – user3637541 Feb 17 '19 at 14:30