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
renderResults
est 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