如何解决跳过顶级 JSON 数据并通过 JavaScript 检索其下方的数据
通过微服务,我检索了几个 JSON 数据包,并将它们输出到 Vue.js 驱动的页面上。数据看起来像这样:
{"data":{"getcompanies":
[
{"id":6,"name":"Arena","address":"12 Baker Street","zip":"15090"},{"id":7,"name":"McMillan","address":null,{"id":8,"name":"Ball","address":"342 Farm Road","zip":"15090"}
]
}}
{"data":{"getusers":
[{"id":22,"name":"Fred","address":"Parmesean Street",{"id":24,"name":"George","address":"Loopy Lane",{"id":25,"name":"Lucy","address":"Farm Road","zip":"15090"}]}}
{"data":{"getdevices":
[{"id":2,"name":"device type 1"},{"id":4,"name":"device type 2"},{"id":5,"name":"device type 3"}]}}
...我通过这样的代码成功地单独抓取了它们:
getCompanies() {
this.sendMicroServiceRequest({
method: 'GET',url: `api/authenticated/function/getcompanies`
})
.then((response) => {
if(response.data) {
this.dataCompanies = response.data.getcompanies
} else {
console.error(response)
}
}).catch(console.error)
}
... getUsers()
和 getDevices()
分别看起来相同。 getCompanies() 返回:
[{"id":6,"zip":"15090"}]
...我将它传递给表格中的 Vue 模板,这很好用。
我正在寻找一种优雅的方式来跳过 response.data.*whatever*
并通过可重复使用的调用访问那些 id 记录,但我无法到达那里。 response.data[0]
不起作用,映射到我需要的东西要么返回未定义,要么返回数组位。并过滤 response.data[0].id
以仅返回带有 id 的行,不断返回未定义的行。
我最后一次尝试(见下文)访问数据确实有效,但看起来它作为单独的数组元素返回。我宁愿不 - 如果可能的话 - 将数组重建为 JSON 结构。我一直在想,我应该能够跨过下一个级别,不管它叫什么,然后把里面的任何东西都放在一块,就像我直接读response.data.getcompanies
一样,但并不在乎'getcompanies
' 是什么,或者需要按名称引用它:
// the call
this.dataCompanies = this.getFullData('companies')
getFullData(who) {
this.sendMicroServiceRequest({
method: 'GET',url: 'api/authenticated/function/get' + who,})
.then((response) => {
if(response) {
// attempt 1 to get chunk below 'getcompanies'
Object.keys(response.data).forEach(function(prop) {
console.log(response.data[prop])
})
// attempt 2
// for (const prop in response.data) {
// console.log(response.data[prop])
// }
let output = response.data[prop] // erroneously thinking this is in one object
return output
} else {
console.error(response)
}
}).catch(console.error)
}
...输出:
(63) [{…},{…},{…}] <-- *there are 63 of these records,I'm just showing the first few...*
0: {"id":6,"zip":"15090"}
1: {"id":7,2: {"id":8,"zip":"15090"}...
哦,上面的 return
由于某种原因在凌晨 3 点让我无法理解。 >.
这是我认为我很接近的事情之一,但并不完全。非常感谢任何正确方向的提示、提示或戳。
解决方法
let arrResponse = {data: ['x']};
let objResponse = {data: {getcompanies: 'x'}};
console.log(arrResponse.data[0]);
console.log(Object.values(objResponse.data)[0]);
response.data[0]
是一个数组,data
会起作用。要获取对象的第一个也是唯一的元素,请改用 Object.values(response.data)[0]
。 Object.values
将对象转换为其值的数组。
其对应的 Object.keys
和 Object.entries
同样分别返回键数组和键值元组。
请注意,对象中的顺序不能保证,因此这只能在您的情况下进行预测,因为 data
恰好只有一个键和值。否则,您必须迭代条目元组并搜索所需条目。
firstValue
让我们从通用函数 firstValue
开始。它将获取对象的第一个值(如果存在),否则会抛出错误 -
const x = { something: "foo" }
const y = {}
const firstValue = t =>
{ const v = Object.values(t)
if (v.length)
return v[0]
else
throw Error("empty data")
}
console.log(firstValue(x)) // "foo"
console.log(firstValue(y)) // Error: empty data
获取数据
现在编写一个通用的 getData
。我们将 firstValue
函数链接到最后,注意不要在此处添加 console.log
或 .catch
;这是调用者决定的选择 -
getData(url) {
return this
.sendMicroServiceRequest({ method: "GET",url })
.then(response => {
if (response.data)
return response.data
else
return Promise.reject(response)
})
.then(firstValue)
}
现在我们写getCompanies
、getUsers
等-
getCompanies() {
return getData("api/authenticated/function/getcompanies")
}
getUsers() {
return getData("api/authenticated/function/getusers")
}
//...
异步和等待
也许你可以用getData
和async
来修饰await
-
async getData(url) {
const response =
await this.sendMicroServiceRequest({ method: "GET",url })
return response.data
? firstValue(response.data)
: Promise.reject(response)
}
展示泛型的力量
我们甚至可能会建议不再需要这些 get*
函数 -
async getAll() {
return {
companies:
await getData("api/authenticated/function/getcompanies"),users:
await getData("api/authenticated/function/getusers"),devices:
await getData("api/authenticated/function/getdevices"),// ...
}
}
上面我们使用了三个按顺序发生的 await getData(...)
请求。也许您希望所有这些请求并行运行。下面我们将展示如何做到这一点 -
async getAll() {
const requests = [
getData("api/authenticated/function/getcompanies"),getData("api/authenticated/function/getusers"),getData("api/authenticated/function/getdevices")
]
const [companies,users,devices] = Promise.all(requests)
return { companies,devices }
}
错误处理
最后,错误处理是为调用者保留的,不应在我们的通用函数中尝试 -
this.getAll()
.then(data => this.render(data)) // some Vue template
.catch(console.error)
,
我觉得明确访问对象会更好。好像对象键和微服务函数的名字是一致的?如果是这样:
getData(functionName) {
return this.sendMicroServiceRequest({
method: 'GET',url: "api/authenticated/function/" + functionName
})
.then( response => response.data[functionName] )
}
getCompanies(){
this.getData("getcompanies").then(companies => {
this.dataCompanies = companies
})
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。