SoftwareBrothers / adminjs

AdminJS is an admin panel for apps written in node.js

Home Page:https://adminjs.co

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to access data sent from frontend to custom endpoint

eakenbor opened this issue · comments

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

@dziraf can you please look int this?

Check req.fields

@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?

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

@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?

@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
}

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.

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

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.