Merhabalar.

Get isteği ile işlemlerimize devam ediyoruz.

Bu yazımda sorguladığımız API endpoint’ine parametre ile veri gönderip data alma işlemini yapacağız.

BlogPost uygulamamıza bu yazımız için bir searchbar yapacağız. Id ile sorgulama yapıp ilgili post’u getirmeye çalışacağız.

İstediğimiz post’u çekebilmek için jsonplaceholder bize aşağıdaki gibi bir endpoint veriyor. Biz de buna istek atacağız.

Burada posts/ kısmından sonra gelen 1 değeri dinamik olacak. O yüzden dinamik olarak buradaki veriyi parametre ile göndermeyi göreceğiz.

https://jsonplaceholder.typicode.com/posts/1

Buraya istek attığımızda elimize gelen data şu şekilde.

Geliştirme Kodlarımız

BlogPost.jsx

import React, { useState } from 'react'
import './BlogPost.css'
import loadingGif from "../../Assets/Images/loading.gif"

const BlogPost = () => {

    const [posts, setPosts] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [isData, setIsData] = useState(false);
    const [isError, setIsError] = useState(null);
    const [showError, setShowError] = useState(false);
    const [searchId, setSearchId] = useState('');


    const loadPosts = async () => {
        try {

            setIsLoading(true);

            const response = await fetch('https://jsonplaceholder.typicode.com/posts');

            if (response.ok) {

                const data = await response.json();

                setPosts(data);

                setIsLoading(false);

                if (data.length === 0 ? setIsData(false) : setIsData(true));

                openMessageModal(`${data.length} posts found`);

            } else {

                setIsLoading(false);
                setIsData(false);
                openMessageModal('There was an error!');
            }

        } catch (error) {

            setIsData(false);
            openMessageModal('There was an error!');
        }
    };

    const openMessageModal = (info) => {

        setIsError(info);
        setShowError(true);
        setTimeout(() => setShowError(false), 5000);
    };

    const getSearchById = async () => {

        try {

            if (searchId === '') {
                loadPosts();
            }

            else {
                const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${searchId}`);

                if (response.ok) {

                    const data = await response.json();
                    setPosts([data]);

                    setIsLoading(false);

                    if (data.length === 0 ? setIsData(false) : setIsData(true));

                    if ([data].length === 0) {
                        openMessageModal('Data not found');
                    }
                    openMessageModal(`${[data].length} posts found`);

                }else {
                    setPosts([]);
                    openMessageModal('Data not found');
                }

            }



        } catch (error) {
            console.error('There was an error!', error);
        }
    }

    const handleSearch = (e) => {

        if (e.target.value === '') {
            loadPosts();
        }

        setSearchId(parseInt(e.target.value));
    }

    return (
        <div className="blogPost">

            <div className='search'>

                <input type="number" name="searchId" value={searchId} onChange={handleSearch} placeholder="Search by ID" />
                <button type='button' onClick={getSearchById}>Search</button>

            </div>

            <button onClick={loadPosts}>Load Posts</button>

            {showError && <div className="error">{isError}</div>}

            {isLoading &&
                <div className="center">
                    <img src={loadingGif} width={100} alt="Loading" />
                </div>
            }

            {!isData &&

                <div className="center">
                    <h3>There is no data</h3>
                </div>
            }

            {isData &&
                posts.map((post) => (
                    <div key={post.id} className="post">
                        <h2>{post.title}</h2>
                        <p>{post.body}</p>
                    </div>
                ))}
        </div>
    );
}

export default BlogPost

BlogPost.css

.blogPost {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.post {
  width: 60%;
  border: 1px solid #ccc;
  border-radius: 5px;
  padding: 20px;
  margin: 20px 0;
  position: relative;
}

button {
  padding: 10px 20px;
  margin: 20px 0;
  border: none;
  border-radius: 5px;
  background-color: #007BFF;
  color: white;
  cursor: pointer;
}

.center {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.error {
  width: 300px;
  height: 50px;
  border-radius: 20px;
  position: fixed;
  top: 20px;
  right: 20px;
  padding: 10px;
  background-color: rgb(255, 0, 0);
  color: white;
  display: flex;
  font-size: 15px;
  font-weight: bold;
  justify-content: center;
  align-items: center;
}







.search {
  margin-top: 20px;
  display: flex;
  direction: column;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 20px;
  width: 50%;
}

.search input {
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  flex-grow: 1;
  margin-right: 10px;
}


.search input, .search button {
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.search button {
  padding: 10px;
  border: none;
  background-color: #007BFF;
  color: white;
  cursor: pointer;
  flex-basis: 10%;
}

.search button:hover {
  background-color: #0056b3;
}

Görüntümüz aşağıdaki gibi olmalı.

State Ekle

searchId isminde bir state oluşturuyoruz.

const [searchId, setSearchId] = useState('');

SearchBox Kodları

<div className='search'>

                <input type="number" name="searchId" value={searchId} onChange={handleSearch} placeholder="Search by ID" />
                <button type='button' onClick={getSearchById}>Search</button>

            </div>

input üzerinde her girilen yeni değerle onChange event’i tetiklenir. Bu event handleSearch fonksiyonunu tetikler.

Eğer value boş ise tüm postların sorgulaması gerçekleştiriliyor. Eğer bir değer varsa searchId değeri güncellenir.

const handleSearch = (e) => {

        if (e.target.value === '') {
            loadPosts();
        }

        setSearchId(parseInt(e.target.value));
    }

getSearchById Fonksiyonu

Search Butonuna basılınca getSearchById fonksiyonu tetiklenir.

const getSearchById = async () => {

        try {

            if (searchId === '') {
                loadPosts();
            }

            else {
                const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${searchId}`);

                if (response.ok) {

                    const data = await response.json();
                    setPosts([data]);

                    setIsLoading(false);

                    if (data.length === 0 ? setIsData(false) : setIsData(true));

                    if ([data].length === 0) {
                        openMessageModal('Data not found');
                    }
                    openMessageModal(`${[data].length} posts found`);

                }else {
                    setPosts([]);
                    openMessageModal('Data not found');
                }

            }



        } catch (error) {
            console.error('There was an error!', error);
        }
    }

Parametre endpoint’e aşağıdaki gibi gönderilir.

fetch(`https://jsonplaceholder.typicode.com/posts/${searchId}`);

Gelen data json’a dönüştürülür.

Tekli data çektiğimizde dizi olarak değil tek bir obje olarak geleceği için posts’u güncellerken doğrudan data’yı değil o datayı dizi içine almış halini göndeririz.

Böylece post üzerinde dönen map işlemini yapabilir.

const data = await response.json();
setPosts([data]);

Kodun devamının açıklamasını şöyle yapabiliriz.

isLoading state’ini false olarak ayarlıyor.

data dizisi boşsa, isData state’ini false olarak ayarlıyor; değilse true olarak ayarlıyor.

Eğer veri dizisi boşsa, ‘Veri bulunamadı’ mesajıyla bir modal açıyor.

Kaç gönderi bulunduğunu belirten bir modal açıyor.

Son olarak, searchId‘yi sıfırlıyor.

} else {
    setPosts([]);
    openMessageModal('Data Not Found');
}

Eğer API’den gelen yanıt başarısızsa, posts state’ini boş bir dizi olarak ayarlıyor ve ‘Veri bulunamadı’ mesajıyla bir modal açıyor.

Uygulama Test

Bu yazımızda böyleydi.

Bir sonraki yazımda görüşmek üzere.


Murat Bilginer
21 Şubat 1992'de doğdum. Endüstri Mühendisi olarak lisansımı 2016 yılında tamamladım. Industryolog Akademi - NGenius oluşumlarının kurucusuyum. Şu anda kendi şirketim Brainy Tech ile Web ve Mobil Geliştirme, AWS, Google Cloud Platform Sistemleri için DevOps, Big Data Analiz ve Görselleştirme hizmetleri sunmakta ve Online Eğitimler vermekteyiz.