Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to access data sent from frontend to custom endpoint #1661

Open
eakenbor opened this issue Apr 22, 2024 · 9 comments
Open

Unable to access data sent from frontend to custom endpoint #1661

eakenbor opened this issue Apr 22, 2024 · 9 comments
Labels
bug Something isn't working

Comments

@eakenbor
Copy link

Contact Details

No response

What happened?

I created a custom endpoint which connects well with the backend, but the data I sent is nowhere to be found.
Here is my code:

//Frontend code
const api = new ApiClient()
 const response = await api.client.request({
            baseURL: api.baseURL,
            url: '/admins/testing',
            method: 'POST',
            data: {
              testing: "hjjhdjfdsjfkdsjfds"
            },
            params: {
              test: "paranananananams"
            }
          })
//adminRouter
adminRouter.post('/admins/testing',
    async (req, res) => {
        try {
            console.log(req.body) //undefined
            console.log( req.params) //{ }
         ...
        } catch (error) {
            return errorResponse(500, error.message, res);
        }
    })

Please @dziraf can you help me with this?

Bug prevalence

Every time

AdminJS dependencies version

"adminjs": "^7.8.1",

What browsers do you see the problem on?

Chrome

Relevant log output

req.body is undefined and req.params is an empty object

Relevant code that's giving you issues

No response

@eakenbor eakenbor added the bug Something isn't working label Apr 22, 2024
@eakenbor
Copy link
Author

@dziraf can you please look int this?

@dziraf
Copy link
Contributor

dziraf commented Apr 23, 2024

Check req.fields

@eakenbor
Copy link
Author

@dziraf thanks, but I am unable to make use of the file I sent to the endpoint. I even used multer to handle it but to no avail.
Please see my codes below. This is how I have always sent files to my nodejs backend.

//Frontend
        const formData = new FormData()
        formData.append("file", file)
        formData.append("key", `sparePartRequests/${sparePartRequest._id}/${uniqueId}-${file.originalname}`)

        const response = await api.client.request({
          baseURL: api.baseURL,
          url: '/custom-admin/upload-fie-to-s3',
          method: 'POST',
          data: formData,
        })
//admin router
const upload = multer({
    limits: {
        fileSize: 1000000
    },
    fileFilter(req, file, cb) {
        if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) {
            return cb(new Error("Please upload an image"))
        }
        cb(undefined, true)
    }
})
adminRouter.post('/custom-admin/upload-fie-to-s3', upload.single("file"), async (req, res) => {
    try {
        const file = req.files.file
        const { key } = req.fields

        const params = {
            Bucket: process.env.DO_SPACES_STORAGE_BUCKET_NAME,
            Key: key,
            Body: file.buffer,
            ContentType: file.type
        }

        await s3.upload(params).promise()

        return successResponse(200, "File successfully uploaded to S3", res, params)

        return
    } catch (error) {
        return errorResponse(500, error.message, res);
    }
})

Please how is it supposed to work?

@dziraf
Copy link
Contributor

dziraf commented Apr 23, 2024

AdminJS uses old formidable middleware for forms, you shouldn't use multer. If you create an AdminJS action instead of an endpoint, the file will be available in request.payload without any extra backend code

@eakenbor
Copy link
Author

@dziraf please how can I use the "old formidable middleware" to send the file to the endpoint? Creating an action is not an option, because nowhere in your documentation is it explained how you can call an action when a custom button inside a frontend code is clicked. Or you have an example?

@eakenbor
Copy link
Author

@dziraf in my original setup above, I could read the file as shown below, but the problem is that I am unable to make use of it and send to s3. Please how am I supposed to upload it to s3?

 File {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  size: 452241,
  path: 'C:\\Users\\efosa\\AppData\\Local\\Temp\\upload_fe34050a693df24591d8d910e1791047',
  name: 'a-black-person-doing-a-home-inspection-617185028.png',
  type: 'image/png',
  hash: null,
  lastModifiedDate: 2024-04-23T13:05:00.900Z,
  _writeStream: WriteStream {
    fd: 4,
    path: 'C:\\Users\\efosa\\AppData\\Local\\Temp\\upload_fe34050a693df24591d8d910e1791047',
    flags: 'w',
    mode: 438,
    start: undefined,
    pos: undefined,
    bytesWritten: 452241,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: true,
      ending: true,
      ended: true,
      finished: true,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      constructed: true,
      prefinished: true,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: true,
      errored: null,
      closed: false,
      closeEmitted: false,
      [Symbol(kOnFinished)]: []
    },
    _events: [Object: null prototype] {},
    _eventsCount: 0,
    _maxListeners: undefined,
    [Symbol(kFs)]: {
      appendFile: [Function: appendFile],
      appendFileSync: [Function: appendFileSync],
      access: [Function: access],
      accessSync: [Function: accessSync],
      chown: [Function: chown],
      chownSync: [Function: chownSync],
      chmod: [Function: chmod],
      chmodSync: [Function: chmodSync],
      close: [Function: close],
      closeSync: [Function: closeSync],
      copyFile: [Function: copyFile],
      copyFileSync: [Function: copyFileSync],
      cp: [Function: cp],
      cpSync: [Function: cpSync],
      createReadStream: [Function: createReadStream],
      createWriteStream: [Function: createWriteStream],
      exists: [Function: exists],
      existsSync: [Function: existsSync],
      fchown: [Function: fchown],
      fchownSync: [Function: fchownSync],
      fchmod: [Function: fchmod],
      fchmodSync: [Function: fchmodSync],
      fdatasync: [Function: fdatasync],
      fdatasyncSync: [Function: fdatasyncSync],
      fstat: [Function: fstat],
      fstatSync: [Function: fstatSync],
      fsync: [Function: fsync],
      fsyncSync: [Function: fsyncSync],
      ftruncate: [Function: ftruncate],
      ftruncateSync: [Function: ftruncateSync],
      futimes: [Function: futimes],
      futimesSync: [Function: futimesSync],
      lchown: [Function: lchown],
      lchownSync: [Function: lchownSync],
      lchmod: undefined,
      lchmodSync: undefined,
      link: [Function: link],
      linkSync: [Function: linkSync],
      lstat: [Function: lstat],
      lstatSync: [Function: lstatSync],
      lutimes: [Function: lutimes],
      lutimesSync: [Function: lutimesSync],
      mkdir: [Function: mkdir],
      mkdirSync: [Function: mkdirSync],
      mkdtemp: [Function: mkdtemp],
      mkdtempSync: [Function: mkdtempSync],
      open: [Function: open],
      openSync: [Function: openSync],
      opendir: [Function: opendir],
      opendirSync: [Function: opendirSync],
      readdir: [Function: readdir],
      readdirSync: [Function: readdirSync],
      read: [Function: read],
      readSync: [Function: readSync],
      readv: [Function: readv],
      readvSync: [Function: readvSync],
      readFile: [Function: readFile],
      readFileSync: [Function: readFileSync],
      readlink: [Function: readlink],
      readlinkSync: [Function: readlinkSync],
      realpath: [Function],
      realpathSync: [Function],
      rename: [Function: rename],
      renameSync: [Function: renameSync],
      rm: [Function: rm],
      rmSync: [Function: rmSync],
      rmdir: [Function: rmdir],
      rmdirSync: [Function: rmdirSync],
      stat: [Function: stat],
      statfs: [Function: statfs],
      statSync: [Function: statSync],
      statfsSync: [Function: statfsSync],
      symlink: [Function: symlink],
      symlinkSync: [Function: symlinkSync],
      truncate: [Function: truncate],
      truncateSync: [Function: truncateSync],
      unwatchFile: [Function: unwatchFile],
      unlink: [Function: unlink],
      unlinkSync: [Function: unlinkSync],
      utimes: [Function: utimes],
      utimesSync: [Function: utimesSync],
      watch: [Function: watch],
      watchFile: [Function: watchFile],
      writeFile: [Function: writeFile],
      writeFileSync: [Function: writeFileSync],
      write: [Function: write],
      writeSync: [Function: writeSync],
      writev: [Function: writev],
      writevSync: [Function: writevSync],
      Dir: [class Dir],
      Dirent: [class Dirent],
      Stats: [Function: Stats],
      ReadStream: [Getter/Setter],
      WriteStream: [Getter/Setter],
      FileReadStream: [Getter/Setter],
      FileWriteStream: [Getter/Setter],
      _toUnixTimestamp: [Function: toUnixTimestamp],
      F_OK: 0,
      R_OK: 4,
      W_OK: 2,
      X_OK: 1,
      constants: [Object: null prototype],
      promises: [Getter]
    },
    [Symbol(kIsPerformingIO)]: false,
    [Symbol(kCapture)]: false
  },
  [Symbol(kCapture)]: false
}

@cetinirfan
Copy link

I'm having the same problem right now, I read the file and send it to the client side, but I guess it doesn't return multiparta because the content-type is application/json, I couldn't find how to change it on the form, and since I'm new to admin.js, I looked at the documentation, but local upload seemed very complicated, now I will try sending it with base64.

@cetinirfan
Copy link

base64 image is working if you want ı can share my code @eakenbor

@eakenbor
Copy link
Author

Thanks @cetinirfan. This is what I did eventually:

import fs from "fs"
 const file = req.files.file
        const { key } = req.fields

        const fileStream = fs.createReadStream(req.files.file.path)

        const params = {
            Bucket: process.env.DO_SPACES_STORAGE_BUCKET_NAME,
            Key: key,
            Body: fileStream,
            ContentType: file.type
        }

        await s3.upload(params).promise()

I hope @dziraf and his team will do justice to their documentation because using this adminjs should not be this painful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants