简体   繁体   中英

Error passing multiple route parameters in a url path

I'm trying to fetch data based on the value of 3 fields ("nkk", "nik" and "nama").

voters-ctrl:

getVotersByParams = async (req, res) => {
        const nkk = req.params.nkk
        const nik = req.params.nik
        const nama = req.params.nama

    await Voter.find({nkk, nik, nama}, (err, voters) => {
        if (err) {
            return res.status(400).json({ success: false, error: err })
        }
        if (!voters.length) {
            return res
                .status(404)
                .json({ success: false, request: req.params, error: `Voter not found` })
        }
        return res.status(200).json({ success: true, data: voters })
    }
}

There is possibilities that one or two of them is empty or not defined by user. The problem is passing multiple paramaters in the url route returns "not found" result when one of the parameters is empty (or not defined):

voters-router:

const express = require('express')

const VotersCtrl = require('../controllers/voters-ctrl')

const router = express.Router()

router.get('/votersbyparams/:nkk/:nik/:nama', VotersCtrl.getVotersByParams)

module.exports = router

The succesfull query result: 在此处输入图像描述

The "not found" query result when the "nkk" parameter is empty: 在此处输入图像描述

How can I solve this problem? Thank you very much in advance.

In your case when one of values can be undefined or empty you should pass all these values in query string rather than parts of route. Query string gives you an possibility to pass only some values.

Read req.query documentation to get an idea how to read these values from query string.

To use URL Params as you are (ie with req.params ) you need to specify them in the URL as follows:

// Browser
fetch(`${apiRoot}/votersby?nkk=${arg1}&nik=${arg3}&nama=${arg3}`)

// Server
router.get(`/votersby`, (req, res) => {
   const { nkk, nik, nama } = req.params
   console.log({ nkk, nik, nama })
   // ...
})

Effectively you are supposed to be using the same endpoint, with different query parameters.

The way you are currently specifying them would actually, conventionally be for:

A) IDs (if there is one /:id B) Looks more like dynamic path (route) building, which you will get 404's for if some of the dynamically generated routes are not found in the API.

See below for more info for specifying a string of parameters:

https://javascript.info/url

I found the answer with using query string rather than multiple route parameters.

Function that handle the search button:

const handleFindClick = async () => {
     const payload = { nkk, nik, nama }
     setIsLoading(true)
     const voters = await api.getVotersByParams(payload)
     setVoters(voters.data.data)
     setIsLoading(false)
     console.log(voters)
    }

The payload data is sending to this api route:

export const getVotersByParams = (payload) => api.get(`/votersbyparams nkk=${payload.nkk}&nik=${payload.nik}&nama=${payload.nama}`)

Finally, a getVotersByParams function that executed in the server:

getVotersByParams = async (req, res) => {
    const {nkk, nik, nama} = req.query
    await Voter.find({nkk : nkk.length > 0 ? nkk : {$exists : true}, nik : nik.length > 0 ? nik : {$exists : true}, nama : nama.length > 0 ? nama : {$exists : true}}, (err, voters) => {
        if (err) {
            return res.status(400).json({ success: false, error: err })
        }
        if (!voters.length) {
            return res
                .status(404)
                .json({ success: false, error: `Voter not found` })
        }
        return res.status(200).json({ success: true, data: voters })
    })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM