如何从嵌套对象生成查询字符串

时间:2019-02-27 19:03:53

标签: javascript reactjs url query-string

我想为我的高级过滤器生成查询字符串。我的对象如下所示:

{
   searchValue: {
     firstName: "John",
     lastName: "Doe",
     postalCode: "3130",
     city: "New York"
   },
    page: 1
 }

我正在使用querystring库来尝试格式化所需的字符串。

export function updateAdvancedSearchQueryString<T>(props: RouteComponentProps, newValues: T) {
  props.history.push({
    pathname: props.location.pathname,
    search: queryString.stringify(newValues)
  });
}

我要实现的输出:

/trainers?page=1&searchValue=firstName=John&lastName=Doe&postalCode=3130&city=New_York

我目前通过此获得的输出:

/trainers?page=1&searchValue=%5Bobject%20Object%5D

如何从嵌套对象生成所需的查询字符串?

2 个答案:

答案 0 :(得分:1)

您可以有很多层次的嵌套,因此您应该递归进行。

应该这样

const data = {
  searchValue: {
    firstName: "John",
    lastName: "Doe",
    postalCode: "3130",
    city: "New York"
  },
  page: 1
}

const createQueryString = (data) => {
  return Object.keys(data).map(key => {
    let val = data[key]
    if (typeof val === 'object') val = createQueryString(val)
    return `${key}=${encodeURIComponent(`${val}`.replace(/\s/g, '_'))}`
  }).join('&')
}

console.log(createQueryString(data))

但是您必须考虑将某些带有函数的对象作为其值之一传递给对象的情况,您将如何处理数组之类的事情。但是基本思路很简单:如果您找到对象作为值,则使用相同的函数将其转换为查询字符串

答案 1 :(得分:0)

作为 Nodejs 和 React 开发的初学者,这是我的问题。花了几天后,我意识到 qs 库做得很好。

您需要导入它

import qs from "qs";

然后在我的情况下在客户端应用程序中使用 React

query = {
   find:{
      sec1:"hi",
      sec2:"there",
   }, 
   limit:12,
   sort:{sec1:-1},
};
const qsg = qs.stringify(query); 
const res = await axios.get(`/api/data?${qsg}`);
console.log("Data from server:", res.data);

在 Nodejs 应用程序中:

const sendData = asyncHandler(async (req, res) => {
console.log("req.query:", req.query);
const {find, sort, limit, ...rest} = req.query
//optimize the query or deconstruct the request

//run the query in my case Mongoose:
const data = await dataModel
.find(find)
.sort(sort)
.limit(limit);

if (data) {
   res.json(data);
} else {
   res.status(404).json({ message: "data not found" });
   res.status(404);
   throw new Error("Data not found");
}