J'obtiens cette erreur
import Search from './models/Search';
import Recipe from './models/Recipe';
import List from './models/List';
import Likes from './models/Likes';
import * as searchView from './views/searchView';
import * as recipeView from './views/recipeView';
import * as listView from './views/listView';
import * as likesView from './views/likesView';
import { elements, renderLoader, clearLoader } from './views/base';
/** Global state of the app
* - Search object
* - Current recipe object
* - Shopping list object
* - Liked recipes
*/
const state = {};
/**
* SEARCH CONTROLLER
*/
const controlSearch = async () => {
// 1) Get query from view
const query = searchView.getInput();
if (query) {
// 2) New search object and add to state
state.search = new Search(query);
// 3) Prepare UI for results
searchView.clearInput();
searchView.clearResults();
renderLoader(elements.searchRes);
try {
// 4) Search for recipes
await state.search.getResults();
// 5) Render results on UI
clearLoader();
searchView.renderResults(state.search.result);
} catch (err) {
console.log(err);
alert('Something wrong with the search...');
clearLoader();
}
}
}
elements.searchForm.addEventListener('submit', e => {
e.preventDefault();
controlSearch();
});
elements.searchResPages.addEventListener('click', e => {
const btn = e.target.closest('.btn-inline');
if (btn) {
const goToPage = parseInt(btn.dataset.goto, 10);
searchView.clearResults();
searchView.renderResults(state.search.result, goToPage);
}
});
/**
* RECIPE CONTROLLER
*/
const controlRecipe = async () => {
// Get ID from url
const id = window.location.hash.replace('#', '');
if (id) {
// Prepare UI for changes
recipeView.clearRecipe();
renderLoader(elements.recipe);
// Highlight selected search item
if (state.search) searchView.highlightSelected(id);
// Create new recipe object
state.recipe = new Recipe(id);
try {
// Get recipe data and parse ingredients
await state.recipe.getRecipe();
state.recipe.parseIngredients();
// Calculate servings and time
state.recipe.calcTime();
state.recipe.calcServings();
// Render recipe
clearLoader();
recipeView.renderRecipe(
state.recipe,
state.likes.isLiked(id)
);
} catch (err) {
console.log(err);
alert('Error processing recipe!');
}
}
};
['hashchange', 'load'].forEach(event => window.addEventListener(event, controlRecipe));
/**
* LIST CONTROLLER
*/
const controlList = () => {
// Create a new list IF there in none yet
if (!state.list) state.list = new List();
// Add each ingredient to the list and UI
state.recipe.ingredients.forEach(el => {
const item = state.list.addItem(el.count, el.unit, el.ingredient);
listView.renderItem(item);
});
}
// Handle delete and update list item events
elements.shopping.addEventListener('click', e => {
const id = e.target.closest('.shopping__item').dataset.itemid;
// Handle the delete button
if (e.target.matches('.shopping__delete, .shopping__delete *')) {
// Delete from state
state.list.deleteItem(id);
// Delete from UI
listView.deleteItem(id);
// Handle the count update
} else if (e.target.matches('.shopping__count-value')) {
const val = parseFloat(e.target.value, 10);
state.list.updateCount(id, val);
}
});
/**
* LIKE CONTROLLER
*/
const controlLike = () => {
if (!state.likes) state.likes = new Likes();
const currentID = state.recipe.id;
// User has NOT yet liked current recipe
if (!state.likes.isLiked(currentID)) {
// Add like to the state
const newLike = state.likes.addLike(
currentID,
state.recipe.title,
state.recipe.author,
state.recipe.img
);
// Toggle the like button
likesView.toggleLikeBtn(true);
// Add like to UI list
likesView.renderLike(newLike);
// User HAS liked current recipe
} else {
// Remove like from the state
state.likes.deleteLike(currentID);
// Toggle the like button
likesView.toggleLikeBtn(false);
// Remove like from UI list
likesView.deleteLike(currentID);
}
likesView.toggleLikeMenu(state.likes.getNumLikes());
};
// Restore liked recipes on page load
window.addEventListener('load', () => {
state.likes = new Likes();
// Restore likes
state.likes.readStorage();
// Toggle like menu button
likesView.toggleLikeMenu(state.likes.getNumLikes());
// Render the existing likes
state.likes.likes.forEach(like => likesView.renderLike(like));
});
// Handling recipe button clicks
elements.recipe.addEventListener('click', e => {
if (e.target.matches('.btn-decrease, .btn-decrease *')) {
// Decrease button is clicked
if (state.recipe.servings > 1) {
state.recipe.updateServings('dec');
recipeView.updateServingsIngredients(state.recipe);
}
} else if (e.target.matches('.btn-increase, .btn-increase *')) {
// Increase button is clicked
state.recipe.updateServings('inc');
recipeView.updateServingsIngredients(state.recipe);
} else if (e.target.matches('.recipe__btn--add, .recipe__btn--add *')) {
// Add ingredients to shopping list
controlList();
} else if (e.target.matches('.recipe__love, .recipe__love *')) {
// Like controller
controlLike();
}
});après avoir recherché disons 'pizza' dans la barre de recherche de mon projet, c'est mon dépôt github: https://github.com/damianjnc/finalforkify
Je pense qu'il pourrait y avoir une erreur dans cette partie du code:
/**
* SEARCH CONTROLLER
*/
const controlSearch = async () => {
// 1) Get query from view
const query = searchView.getInput();
if (query) {
// 2) New search object and add to state
state.search = new Search(query);
// 3) Prepare UI for results
searchView.clearInput();
searchView.clearResults();
renderLoader(elements.searchRes);
try {
// 4) Search for recipes
await state.search.getResults();
// 5) Render results on UI
clearLoader();
searchView.renderResults(state.search.result);
} catch (err) {
console.log(err);
alert('Something wrong with the search...');
clearLoader();
}
}
}
elements.searchForm.addEventListener('submit', e => {
e.preventDefault();
controlSearch();
});
dans le fichier searchView.js:
import { elements } from './base';
export const getInput = () => elements.searchInput.value;
export const clearInput = () => {
elements.searchInput.value = '';
};
export const clearResults = () => {
elements.searchResList.innerHTML = '';
elements.searchResPages.innerHTML = '';
};
export const highlightSelected = id => {
const resultsArr = Array.from(document.querySelectorAll('.results__link'));
resultsArr.forEach(el => {
el.classList.remove('results__link--active');
});
document.querySelector(`.results__link[href*="${id}"]`).classList.add('results__link--active');
};
/*
// 'Pasta with tomato and spinach'
acc: 0 / acc + cur.length = 5 / newTitle = ['Pasta']
acc: 5 / acc + cur.length = 9 / newTitle = ['Pasta', 'with']
acc: 9 / acc + cur.length = 15 / newTitle = ['Pasta', 'with', 'tomato']
acc: 15 / acc + cur.length = 18 / newTitle = ['Pasta', 'with', 'tomato']
acc: 18 / acc + cur.length = 24 / newTitle = ['Pasta', 'with', 'tomato']
*/
export const limitRecipeTitle = (title, limit = 17) => {
const newTitle = [];
if (title.length > limit) {
title.split(' ').reduce((acc, cur) => {
if (acc + cur.length <= limit) {
newTitle.push(cur);
}
return acc + cur.length;
}, 0);
// return the result
return `${newTitle.join(' ')} ...`;
}
return title;
}
const renderRecipe = recipe => {
const markup = `
<li>
<a class="results__link" href="#${recipe.recipe_id}">
<figure class="results__fig">
<img src="${recipe.image_url}" alt="${recipe.title}">
</figure>
<div class="results__data">
<h4 class="results__name">${limitRecipeTitle(recipe.title)}</h4>
<p class="results__author">${recipe.publisher}</p>
</div>
</a>
</li>
`;
elements.searchResList.insertAdjacentHTML('beforeend', markup);
};
// type: 'prev' or 'next'
const createButton = (page, type) => `
<button class="btn-inline results__btn--${type}" data-goto=${type === 'prev' ? page - 1 : page + 1}>
<span>Page ${type === 'prev' ? page - 1 : page + 1}</span>
<svg class="search__icon">
<use href="img/icons.svg#icon-triangle-${type === 'prev' ? 'left' : 'right'}"></use>
</svg>
</button>
`;
const renderButtons = (page, numResults, resPerPage) => {
const pages = Math.ceil(numResults / resPerPage);
let button;
if (page === 1 && pages > 1) {
// Only button to go to next page
button = createButton(page, 'next');
} else if (page < pages) {
// Both buttons
button = `
${createButton(page, 'prev')}
${createButton(page, 'next')}
`;
} else if (page === pages && pages > 1) {
// Only button to go to prev page
button = createButton(page, 'prev');
}
elements.searchResPages.insertAdjacentHTML('afterbegin', button);
};
export const renderResults = (recipes, page = 1, resPerPage = 10) => {
// render results of currente page
const start = (page - 1) * resPerPage;
const end = page * resPerPage;
recipes.slice(start, end).forEach(recipe => renderRecipe(recipe));
// render pagination buttons
renderButtons(page, recipes.length, resPerPage);
};
Le code qui appelle la fonction renderResults est dans le fichier index.js . Voici cette partie du code:
export const renderResults = (recipes, page = 1, resPerPage = 10) => {
// render results of currente page
const start = (page - 1) * resPerPage;
const end = page * resPerPage;
recipes.slice(start, end).forEach(recipe => renderRecipe(recipe));
// render pagination buttons
renderButtons(page, recipes.length, resPerPage);
};
et le fichier index.js complet:
TypeError: Cannot read property 'slice' of undefined
at Object.renderResults (searchView.js:93)
at _callee$ (index.js:85)
at tryCatch (runtime.js:65)
at Generator.invoke [as _invoke] (runtime.js:303)
at Generator.prototype.(:8081/anonymous function) [as next] (webpack:///./node_modules/babel-polyfill/node_modules/regenerator-runtime/runtime.js?:117:21)
at step (index.js:41)
at eval (index.js:41)
3 Réponses :
J'obtenais également la même erreur.
C'est probablement parce que votre utilisation a atteint sa limite de 50 appels par jour.
Attendez demain ou créez un autre compte et utilisez une nouvelle clé.
cela a fonctionné pour moi. :)
J'obtenais également la même erreur.
Après avoir obtenu cette erreur, je savais que lorsque tableau ou tout ce que vous utilisez avec slice () undefined ou null.
C'est pourquoi cette erreur se produit.
> Index:103 Uncaught TypeError: Cannot read property 'slice' of > undefined > at Object.success (Index:103) > at fire (jquery-1.12.4.js:3232) > at Object.fireWith [as resolveWith] (jquery-1.12.4.js:3362) > at done (jquery-1.12.4.js:9840) > at XMLHttpRequest.callback (jquery-1.12.4.js:10311)
Erreur
response(dd.slice(0, 20));
Oui c'est vrai. Essayez de faire une bonne valeur de débogage que vous utilisez slice
slice fonctionne sur une chaîne alors assurez-vous que dd est une chaîne ou faites dd.toString (). slice (to, from);
Oui ... appeler .toString () sur undefined n'aidera pas.
On dirait que
renderResultsest appelé sans argument, ou avec un premier argument non défini? (mais le code qui l'appelle n'a pas été posté ...)vient de le publier ci-dessus