-1

I have this line of html in my view: <div id="ajax" data-value="photos_path"></div>

And then in my js I do this:

import 'uppy/dist/uppy.min.css'
import '@uppy/core/dist/style.min.css'
import '@uppy/webcam/dist/style.min.css'

import {
 Core,
 Dashboard,
 Webcam,
 AwsS3,
} from 'uppy'

function fileUpload(fileInput) {
 const hiddenInput = document.querySelector('.upload-data'),
 const post_url = document.getElementById('ajax').getAttribute('data-value'),
 const s3_url = document.getElementById('s3').getAttribute('data-value')

 const uppy = Core({
  autoProceed: true,
  allowMultipleUploads: true,
  restrictions: {
    maxFileSize: 10000000,
    maxNumberOfFiles: 10,
    allowedFileTypes: ['image/jpeg', 'image/png']
  }
})
.use(Dashboard, {
  inline: true,
  target: '#file-uppy',
  trigger: '.upload-file',
  hideUploadButton: true,
  replaceTargetContent: false,
  showProgressDetails: true,
  width: 1200,
  height: 400,
})
.use(Webcam, {
  target: Dashboard,
})
.use(AwsS3, {
  companionUrl: s3_url,
})

uppy.on('upload-success', (file, response) => {
 const uploadedFileData = {
  id: file.meta['key'].match(/^cache\/(.+)/)[1], // object key without prefix
  storage: 'cache',
   metadata: {
    size: file.size,
    filename: file.name,
    mime_type: file.type,
   }
  }
  $.ajax({
   type: "POST", 
   url: post_url,
   data: { 
    photo: {
     image: uploadedFileData
    }
   }
  })
 })
}

export default fileUpload

Yet for some reason the js is not compiling. I get this error: Uncaught ReferenceError: post_url is not defined. Seems to me it is defined? In fact I do the same thing for another data value. <div id="s3" data-value="docs"></div> in the view and s3 = document.getElementById('s3').getAttribute('data-value'). This works just perfect.

Why does one work and the other does not?

calyxofheld
  • 1,538
  • 3
  • 24
  • 62

1 Answers1

1

Change this:

post_url = document.getElementById('ajax').getAttribute('data-value')

To this:

const post_url = document.getElementById('ajax').getAttribute('data-value')

Differently from python and ruby in javascript you need to put a keyword (const, let or var) to declare variables or constants.

crocarneiro
  • 134
  • 8
  • 3
    A declaration is not required, the variable is created to the global scope without the declaration. It also will behave a bit different compared to declared globals, but this won't fix OP's issue. – Teemu Mar 22 '21 at 20:36
  • it *did* solve it though. why does the `s3` one work without the declaration? – calyxofheld Mar 22 '21 at 20:37
  • 1
    @calyxofheld If it fixed the problem, then there's something in your code overriding the value before you use it. What ever it is, it's good practice to always declare your variables, of course. – Teemu Mar 22 '21 at 20:38
  • 2
    The reasoning in the answer is only true in strict mode scripts (or modules). – Sebastian Simon Mar 22 '21 at 20:44
  • 1
    @calyxofheld `s3` worked because of this: [Do DOM tree elements with ids become global variables?](https://stackoverflow.com/q/3434278/4642212). IDs (unfortunately) become global `window` properties, implicitly, so assigning to `s3` actually assigns to `window.s3` which already exists. – Sebastian Simon Mar 22 '21 at 20:45
  • 1
    @Teemu and @Sebastian Simon, you guys are right. But I did not know whether the OP has a `'use strict'` in the beggining of his script, thus my answer. – crocarneiro Mar 22 '21 at 20:49
  • 2
    A nice catch from @Sebastian, I didn't think about strict mode at all. Additionally to the mentioned cases, also `class` definition is run in strict mode. – Teemu Mar 22 '21 at 20:50
  • i just added the full js file to the OP. i'm not sure what i'm doing wrong, but it appears that declaring too many `const` results in a syntax error: `Unexpected keyword 'const' (14:2)`. why is that? – calyxofheld Mar 22 '21 at 23:24
  • @calyxofheld it's because you have commas (,) between the constant declarations. Remove the final comma in the lines 13 and 14 and it'll work – crocarneiro Mar 23 '21 at 13:00