Tutorial Laravel 9 dan Next.js #6 : Edit dan Update Data di Next.js


Tutorial Laravel 9 dan Next.js #6 : Edit dan Update Data di Next.js

Halo teman-teman semuanya, di artikel sebelumnya kita telah belajar bagaimana cara melakukan proses insert data ke dalam database. Sekarang kita akan lanjutkan belajar bagaimana cara membuat proses edit dan update data ke dalam database di dalam Next.js.

Langkah 1 - Mengaktifkan Link Edit

Pertama, kita akan mengaktifkan link untuk proses edit data di dalam halaman posts index. Silahkan buka file pages/posts/index.js, kemudian cari kode berikut ini.

<button className="btn btn-sm btn-primary border-0 shadow-sm mb-3 me-3">EDIT</button>

Dan ubahlah menjadi seperti berikut ini.

<Link href={`/posts/edit/${post.id}`}>
   <button className="btn btn-sm btn-primary border-0 shadow-sm mb-3 me-3">EDIT</button>
</Link>

Di atas, kita bungkus button EDIT dengan Link yang ada di Next.js dan kita berikan URL ke /posts/edit/:id.

Langkah 2 - Membuat Page Edit Post

Setelah berhasil menambahkan link untuk proses edit data, sekarang kita akan lanjutkan membuat halaman page / view-nya.

Silahkan buat folder baru dengan nama edit di dalam folder pages/posts dan di dalam folder edit silahkan buat file baru dengan nama [id].js, kemudian masukkan kode berikut ini di dalamnya.

//import hook useState
import { useState } from 'react';

//import router
import Router from 'next/router';

//import layout
import Layout from '../../../components/layout';

//import axios
import axios from "axios";

//fetch with "getServerSideProps"
export async function getServerSideProps({ params }) {

    //http request
    const req  = await axios.get(`${process.env.NEXT_PUBLIC_API_BACKEND}/api/posts/${params.id}`)
    const res  = await req.data.data

    return {
      props: {
          post: res // <-- assign response
      },
    }
  }

function PostEdit(props) {

    //destruct
    const { post } = props;

    //state
    const [image, setImage] = useState("");
    const [title, setTitle] = useState(post.title);
    const [content, setContent] = useState(post.content);

    //state validation
    const [validation, setValidation] = useState({});

    //function "handleFileChange"
    const handleFileChange = (e) => {

        //define variable for get value image data
        const imageData = e.target.files[0]

        //check validation file
        if (!imageData.type.match('image.*')) {

            //set state "image" to null
            setImage('');

            return
        }

        //assign file to state "image"
        setImage(imageData);
    }

    //method "updatePost"
    const updatePost = async (e) => {
        e.preventDefault();

        //define formData
        const formData = new FormData();

        //append data to "formData"
        formData.append('image', image);
        formData.append('title', title);
        formData.append('content', content);
        formData.append('_method', 'PUT');
        
        //send data to server
        await axios.post(`${process.env.NEXT_PUBLIC_API_BACKEND}/api/posts/${post.id}`, formData)
        .then(() => {

            //redirect
            Router.push('/posts')

        })
        .catch((error) => {

            //assign validation on state
            setValidation(error.response.data);
        })
        
    };

    return (
        <Layout>
            <div className="container" style={{ marginTop: '80px' }}>
                <div className="row">
                    <div className="col-md-12">
                        <div className="card border-0 rounded shadow-sm">
                            <div className="card-body">
                                <form onSubmit={ updatePost }>

                                    <div className="form-group mb-3">
                                        <label className="form-label fw-bold">Image</label>
                                        <input type="file" className="form-control" onChange={handleFileChange}/>
                                    </div>

                                    <div className="form-group mb-3">
                                        <label className="form-label fw-bold">TITLE</label>
                                        <input className="form-control" type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Masukkan Title" />
                                    </div>
                                    {
                                        validation.title &&
                                            <div className="alert alert-danger">
                                                {validation.title}
                                            </div>
                                    }

                                    <div className="form-group mb-3">
                                        <label className="form-label fw-bold">CONTENT</label>
                                        <textarea className="form-control" rows={3} value={content} onChange={(e) => setContent(e.target.value)} placeholder="Masukkan Content" />
                                    </div>
                                    {
                                        validation.content &&
                                            <div className="alert alert-danger">
                                                {validation.content}
                                            </div>
                                    }

                                    <button className="btn btn-primary border-0 shadow-sm" type="submit">
                                        UPDATE
                                    </button>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </Layout>
    );

}

export default PostEdit

Dari penambahan kode di atas, pertama kita import hook useState dari React.js.

//import hook useState
import { useState } from 'react';

Kemudian kita import Router dari Next.js.

//import router
import Router from 'next/router';

Dan kita import layout yang akan kita gunakan sebagai induk template.

//import layout
import Layout from '../../../components/layout';

Dan terakhir kita import Axios.

//import axios
import axios from "axios";

Di bawahnya kita membuat function getServerSideProps. Dan di dalam function tersebut kita tambahkan parameter params. Tujuannya agar kita bisa mendapatkan nilai dari parameter di URL browser.

//fetch with "getServerSideProps"
export async function getServerSideProps({ params }) {

	//...

}

Di dalamnya kita melakukan HTTP request menggunakan Axios ke dalam endpoint /api/posts/:id dengan method GET.

const req  = await axios.get(`${process.env.NEXT_PUBLIC_API_BACKEND}/api/posts/${params.id}`)

Jika proses get response data berhasil dilakukan, maka kita akan masukkan ke dalam variable res.

const res  = await req.data.data

Dan kita akan return menggunakan props yang bernama post dengan isi dari variable res1.

return {
  props: {
    post: res // <-- assign response
  },
}

Dan kita membuat function component yang bernama PostEdit yang di dalam function tersebut kita berikan parameter props. Tujuannya agar kita bisa mengakses data props di dalam function component tersebut.

function PostEdit(props) {

	//...
	
}

Di dalamnya, pertama kita lakukan destructuring variable post yang ada di dalam props.

const { post } = props;

Setelah itu, kita define 3 state yang mana, di dalamnya kita berikan value dari data props post.

const [image, setImage] = useState("");
const [title, setTitle] = useState(post.title); // <-- assign value from props 
const [content, setContent] = useState(post.content); <-- assign value from props

Di bawahnya, kita define 1 state lagi untuk validation.

const [validation, setValidation] = useState({});

Dan kita buat sebuah method dengan nama handleFileChange. Method ini akan digunakan untuk meng-handle image yang akan diupload dan di dalamnya kita memeriksa, apakah file yang akan diupload sudah sesuai formatnya.

//function "handleFileChange"
const handleFileChange = (e) => {

    //define variable for get value image data
    const imageData = e.target.files[0]

    //check validation file
    if (!imageData.type.match('image.*')) {

        //set state "image" to null
        setImage('');

        return
    }

    //assign file to state "image"
    setImage(imageData);
}

Kemudian kita buat method dengan nama updatePost. Method ini yang akan digunakan untuk melakukan proses update data. Dan method ini akan dijalankan ketika form di submit.

<form onSubmit={ updatePost }>

	//...
	
</form>
//method "updatePost"
const updatePost = async (e) => {

	//...
	
}

Di dalam method updatePost, pertama kita meng-inisialisasi formData terlebih dahulu. Ini akan kita gunakan untuk menampung data sebelum data tersebut kita kirimkan ke dalam server.

//define formData
const formData = new FormData();

Setelah melakukan inisialisasi, sekarang kita lanjutkan untuk melakukan append atau memasukkan data yang ada di dalam state ke dalam formData.

formData.append('image', image);
formData.append('title', title);
formData.append('content', content);
formData.append('_method', 'PUT');

Di atas, kita tambahkan 1 key yaitu _method dengan value PUT. Karena ini adalah proses update data. Setelah data berhasil ditambahkan di dalam formData, sekarang kita lanjutkan untuk mengirimkannya ke dalam server.

await axios.post(`${process.env.NEXT_PUBLIC_API_BACKEND}/api/posts/${post.id}`, formData)

Di atas, kita mengirimkan data-nya menggunakan Axios dengan method POST ke dalam endpoint /api/posts:/id.

Jika proses update data berhasil, kita akan redirect ke dalam URL /posts.

Router.push('/posts')

Dan jika proses update data gagal dilakukan, maka kita akan assign ke dalam state yang bernama validation.

setValidation(error.response.data);

Langkah 3 - Uji Coba Edit dan Update Data

Silahkan klik button EDIT di salah satu data yang teman-teman miliki, jika berhasil maka akan menampilkan halaman form edit data, kurang lebih seperti berikut ini.

Dan silahkan disesuaikan data yang akan diupdate, kemudian klik button UPDATE. Jika berhasil maka kita akan diarahkan ke dalam halaman posts index dengan data yang telah diperbarui.

Kurang lebih seperti itu, cara bagaimana membuat proses edit dan update data di dalam Next.js dengan Rest APi yang dibuat di dalam Laravel.

Di artikel selanjutnya kita semua akan belajar bagaimana cara membuat proses delete data di dalam Next.js dengan memanggil Rest API yang ada di dalam Laravel.

Terima Kasih



Fika Ridaul Maulayya
Full-Stack Developer, Content Creator and CO-Founder SantriKoding.com

Suka dengan tulisan di SantriKoding? Kamu bisa memberikan dukungan dengan berdonasi atau bagikan konten ini di sosial media. Terima kasih atas dukungan Anda!

KEBIJAKAN KOMENTAR

Saat memberikan komenatar silahkan memberikan informasi lengkap tentang error, seperti: screenshot, link kode, dll. Baca aturan komentar kami