我想一次单击调用两个函数并确保它们能依次运行
2020-03-24
753
我想得到帮助来解决我试图解决的一个问题,所以问题是我必须调用两个 API url。第二个依赖于第一个(在第一次获取中,我获取了一些基本信息,包括 id,在第二次获取中,我想根据第一次获取的 id 获取数据)。
我总是得到这个错误:
Uncaught TypeError:无法读取未定义的属性“length”
可能我的方法不正确。我尝试了一些方法,比如将第二个函数放在第一个函数中,我尝试在不使用异步的情况下执行此操作,它仅在我有两个不同的按钮时才有效。
我猜是异步导致了这个问题。(它试图在响应之前获取长度)
请帮助我解决这个问题。我很想了解一些关于方法的见解或任何解决方法。
提前谢谢。
这是有问题的代码
//recipies by ingredients array
var displayData = [];
//full recipies array
var displayRecipes = [];
document.getElementById("search").addEventListener("click", function () {
var l = document.getElementsByClassName("ingInput").length
var ing = document.getElementById('id').value
var ing1 = ''
//getting all the values from the inputs so i can search it in the api url
for(var i = 1; i<l ;i++){
ing1 += ',' + document.getElementsByClassName("ingInput")[i].value
}
//async get request for the api url
async function postData(url = '') {
const response = await fetch(url, {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
});
return response.json(); // parses JSON response into native JavaScript objects
}
//the api url with the inputs values for searching by ingredeints
postData('https://api.spoonacular.com/recipes/findByIngredients?ingredients='+ ing + ing1 + '&number=10&apiKey=API_KEY')
.then((data) => {
displayData.push(data); // JSON data parsed by `response.json()` call
console.log('done')
});
})
//second func
document.getElementById("search").addEventListener("click", function () {
//trying to get data from this array, here i have error.
var l = displayData[0].length
var ids = []
for(var i = 0; i<l ;i++){
ids.push(displayData[0][i].id)
}
async function postData(url = '') {
// Default options are marked with *
const response = await fetch(url, {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
});
return await response.json(); // parses JSON response into native JavaScript objects
}
postData('https://api.spoonacular.com/recipes/informationBulk?ids='+ids.toString()+'&apiKey=API_KEY')
.then((data) => {
displayRecipes.push(data); // JSON data parsed by `response.json()` call
console.log(displayRecipes)
});
})```
2个回答
如果只有第一次获取数据,您才可以进行第二次获取。这样,当没有数据时,按钮会获取初始数据。如果数据已经存在,它会获取附加信息。因此,您有一个侦听器:
document.getElementById( "search" ).addEventListener( "click", function () {
if ( displayData.length === 0 ) {
// Call first function
} else {
// Call second function
}
})
PJohnson
2020-03-24
我找到了一个解决方案,我不确定这是否是最好的方法,但对我来说效果很好。 所以 dom 看起来像这样: (我在搜索按钮中添加了 onclick)
<div id="container">
<!-- first input for the first ingrediant you can search -->
<input type="text" class="ingInput" id="id" placeholder="ingrediant" onfocus="auto(this)">
</div>
<!-- search button, first bring the recipies based on ingredient, then the full recipies based on ids from the first fetch data -->
<button id="search" onclick="asyncCall()">Search</button>
<!-- add new input for more ingrediant -->
<button id="add" onclick="add()">Add</button>
<!-- display the element i have created from the data i have -->
<div id="display">
</div>
<!-- for jquery pagination -->
<button id="btn_prev">Prev</button>
<button id="btn_next">Next</button>
page: <span id="page"></span>
以及用于获取数据的 javascript(首先从第一个 api 链接,然后从第二个 api 链接):
//recipies by ingredients array
var displayData = [];
//full recipies array
var displayRecipes = [];
async function search(){
var l = document.getElementsByClassName("ingInput").length
var ing = document.getElementById('id').value
var ing1 = ''
//getting all the values from the inputs so i can search it in the api url
for(var i = 1; i<l ;i++){
ing1 += ',' + document.getElementsByClassName("ingInput")[i].value
}
//the api url with the inputs values for searching by ingredeints
await fetch('https://api.spoonacular.com/recipes/findByIngredients?ingredients='+ ing + ing1 + '&number=10&apiKey=API_KEY', {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
}
}).then(res => res.json())
.then((data) => {
displayData.push(data); // JSON data parsed by `response.json()` call
console.log('done')
});
}
async function getRecipes(){
var l = displayData[0].length
var ids = []
for(var i = 0; i<l ;i++){
ids.push(displayData[0][i].id)
}
await fetch('https://api.spoonacular.com/recipes/informationBulk?ids='+ids.toString()+'&apiKey=API_KEY',{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
}
})
.then(res => res.json())
.then((data) => {
displayRecipes.push(data); // JSON data parsed by `response.json()` call
console.log(displayRecipes)
});
}
async function asyncCall() {
console.log('calling');
const resultSearch = await search();
console.log('done await search');
console.log('calling2');
const resultRecipies = await getRecipes();
console.log('done await recipes');
}```
Elna Haim
2020-03-25