---
# System prepended metadata

title: '小專案八: Meal Finder | 連結API製作菜單搜尋器'
tags: [JS小專案]

---

# 小專案八: Meal Finder | 連結API製作菜單搜尋器
###### tags: `JS小專案`


本章節目的: 透過連結API可以切出一個可搜尋的介面
![](https://i.imgur.com/rQ9uh4u.jpg)
[網頁連結](https://leonsika.github.io/my_projects/008_Meal_Finder/index.html)

## 學習重點_html

### 如何架出簡潔的搜尋欄?
![](https://i.imgur.com/TIYg1KV.png)
1. 學習重點: class的命名
2. 使用Font Awesome來找適合的icon
[參考資料_Font Awesome](https://fontawesome.com/v5.15/icons/search)

```htmlembedded=
<div class="flex">
<!-- 使用Class: flex讓所包含的東西都會水平呈現 -->
      <form class="flex" id="submit">
        <input type="text" id="search" placeholder="Search for meals or keywords" />
        
        <button class="search-btn" type="submit">
<!--從font-awesome來找適合的icon來輸入-->
          <i class="fas fa-search"></i>
        </button>
      </form>  
      <button class="random-btn" id="random">
        <i class="fas fa-random"></i>
      </button>
    
    </div>
```

## 學習重點_css

### 使用Grid讓圖像四個為一列來排列
![](https://i.imgur.com/zc1inlU.jpg)


```css=
.meals {
  display: grid;
/*  display設立為grid  */
  grid-template-columns: repeat(4, 1fr);
/* 設定成每四個為一列 */
  grid-gap: 20px;
  margin-top: 20px;
}
```

## 學習重點_Javascript

### 用fetch來連API
總之就是用fetch，我有空再來研究一下

```javascript=
// Search meal and fetch from API
function searchMeal(e) {
  e.preventDefault();

  // Clear single meal
  single_mealEl.innerHTML = '';

  // Get search term
  const term = search.value;


  // Check for empty
  // 連上themealdb的API找菜單

if (term.trim()) {
  fetch(`https://www.themealdb.com/api/json/v1/1/search.php?s=${term}`)
    .then(res => res.json())
    .then(data => {
      console.log(data);
      resultHeading.innerHTML = `<h2>Search results for '${term}':</h2>`;

      if (data.meals === null) {
        resultHeading.innerHTML = `<p>There are no search results. Try again!<p>`;
      } else {
        mealsEl.innerHTML = data.meals
          .map(
            meal => `
          <div class="meal">
            <img src="${meal.strMealThumb}" alt="${meal.strMeal}" />
            <div class="meal-info" data-mealID="${meal.idMeal}">
              <h3>${meal.strMeal}</h3>
            </div>
          </div>
        `
          )
          .join('');
      }
    });
  // Clear search text
  search.value = '';
} else {
  alert('Please enter a search term');
}
}

// Fetch meal by ID
function getMealById(mealID) {
  fetch(`https://www.themealdb.com/api/json/v1/1/lookup.php?i=${mealID}`)
  .then(res => res.json())
  .then(data => {
    const meal = data.meals[0];

    addMealToDOM(meal);
  });
}

// Fetch random meal from API
function getRandomMeal() {
  // Clear meals and heading
  mealsEl.innerHTML = '';
  resultHeading.innerHTML = '';

  fetch(`https://www.themealdb.com/api/json/v1/1/random.php`)
  .then(res => res.json())
  .then(data => {
    const meal = data.meals[0];
    addMealToDOM(meal);
  });
}



// Add meal to DOM
function addMealToDOM(meal) {
  const ingredients = [];

  for (let i = 1; i <= 20; i++) {
    if (meal[`strIngredient${i}`]) {
      ingredients.push(
        `${meal[`strIngredient${i}`]} - ${meal[`strMeasure${i}`]}`
      );
    } else {
      break;
    }
  }

  // 讓list標籤圖像化
  single_mealEl.innerHTML = `
    <div class="single-meal">
      <h1>${meal.strMeal}</h1>
      <img src="${meal.strMealThumb}" alt="${meal.strMeal}" />
      <div class="single-meal-info">
        ${meal.strCategory ? `<p>${meal.strCategory}</p>` : ''}
        ${meal.strArea ? `<p>${meal.strArea}</p>` : ''}
      </div>
      <div class="main">
        <p>${meal.strInstructions}</p>
        <h2>Ingredients</h2>
        <ul>
          ${ingredients.map(ing => `<li>${ing}</li>`).join('')}
        </ul>
      </div>
    </div>
  `;
}
```