Tutorial Rajaongkir dengan Laravel, Vue Js dan Tailwind CSS#5 : Integrasi Rajaongkir dengan Vue Js


Tutorial Rajaongkir dengan Laravel, Vue Js dan Tailwind CSS#5 : Integrasi Rajaongkir dengan Vue Js

Halo teman-teman semuanya, di artikel sebelumnya kita telah belajar bagaimana cara installasi dan konfigurasi Tailwind CSS di dalam project Vue Js, sekarang kita lanjutkan bagaimana cara mengintegrasikan Laravel sebagai Backend dan mengambil data dari RajaOngkir.

Langkah 1 - Installasi Axios

Pertama, kita akan laukan installasi library Axios terlebih dahulu di dalam project Vue Js, Axios di gunakan untuk melakukan HTTP Request dari client yaitu Vue Js ke dalam server yaitu Laravel. Disini kita bisa melakukan berbagai macam method request, seperti GET, POST, PUT, PATCH DELETE.

Silahkan jalankan perintah berikut ini di dalam terminal/CMD :

npm install axios

Silahkan tunggu proses installasinya sampai selesai.

Langkah 2 - Menghitung Biaya Ongkos Kirim

Sekarang, kita lanjutkan untuk mengintegrasikan Vue Js dan Laravel untuk mendapatkan biaya ongkos kirim, silahkan buka file src/App.vue, kemudian ubah semua kode-nya menjadi seperti berikut ini :

<template>
  <div>
    <div class="p-4 bg-gray-600 shadow-sm text-center text-white">
      VUE - TAILWIND CSS - RAJA ONGKIR - SANTRIKODING.COM
    </div>

    <div class="grid sm:grid-cols-12 md:grid-cols-4 gap-4 p-4">
      <div class="bg-white p-3 shadow-sm rounded">
        <h4 class="text-xl pb-1">ORIGIN</h4>
        <hr class="border-2">
         <div class="mt-4 pb-2">
           <label class="mb-2">PROVINSI</label>
           <select class="w-full border bg-white rounded px-3 py-2 outline-none" @change="getCitiesOrigin" v-model="state.province_origin">
            <option class="py-1" v-for="province in provinces" :key="province.id" :value="province.province_id">{{ province.province }}</option>
          </select>
         </div>
         <div class="mt-4 pb-2">
           <label class="mb-2">KABUPATEN</label>
           <select class="w-full border bg-white rounded px-3 py-2 outline-none" v-model="state.city_origin">
            <option class="py-1" v-for="city in cities_origin" :key="city.id" :value="city.city_id">{{ city.city_name }}</option>
          </select>
         </div>
      </div>
      <div class="bg-white p-3 shadow-sm rounded">
        <h4 class="text-xl pb-1">DESTINATION</h4>
        <hr class="border-2">
        <div class="mt-4 pb-2">
           <label class="mb-2">PROVINSI</label>
           <select class="w-full border bg-white rounded px-3 py-2 outline-none" @change="getCitiesDestination" v-model="state.province_destination">
            <option class="py-1" v-for="province in provinces" :key="province.id" :value="province.province_id">{{ province.province }}</option>
          </select>
         </div>
         <div class="mt-4 pb-2">
           <label class="mb-2">KABUPATEN</label>
           <select class="w-full border bg-white rounded px-3 py-2 outline-none" v-model="state.city_destination">
            <option class="py-1" v-for="city in cities_destination" :key="city.id" :value="city.city_id">{{ city.city_name }}</option>
          </select>
         </div>
      </div>
      <div class="bg-white p-3 shadow-sm rounded">
        <h4 class="text-xl pb-1">KURIR</h4>
        <hr class="border-2">
        <div class="mt-4 pb-2">
          <label class="mb-2">KURIR</label>
           <select class="w-full border bg-white rounded px-3 py-2 outline-none" v-model="state.courier">
            <option class="py-1" value="jne">JNE</option>
            <option class="py-1" value="tiki">TIKI</option>
            <option class="py-1" value="pos">POS</option>
          </select>
         </div>
         <div class="mt-4 pb-2">
          <label class="mb-2">BERAT <i>(Gram)</i> </label>
          <input type="text" class="p-2 bg-gray-200 rounded w-full shadow hover:bg-white" v-model="state.weight" placeholder="Masukkan Berat (Gram)">
         </div>
      </div>
      <div>
        <button class="bg-blue-500 p-3 shadow-sm rounded text-white hover:bg-blue-700 focus:outline-none" @click="getCostOngkir">CEK ONGKOS KIRIM</button>
      </div>
    </div>

    <div class="grid sm:grid-cols-1 md:grid-cols-1 gap-4 p-4" v-if="resultCost">
      <div class="bg-white p-3 shadow-sm rounded">
        <h4 class="text-xl pb-1">HASIL ONGKOS KIRIM</h4>
        <hr class="border-2">
        <div class="mt-4" v-for="(value, index) in resultCost" :key="index">
            {{ value.service }} - {{ value.cost[0].value }} - {{ value.cost[0].etd }} Hari
            <hr>
        </div>
      </div>
    </div>

  </div>
</template>

<script>

import { onMounted, reactive, ref } from 'vue'
import axios from 'axios'

  export default {

    setup() {

      /**
       * state province
       */
      const provinces = ref({})

      /**
       * state ID for province and city
       */
      const state = reactive({
        
        province_origin: "",
        city_origin: "",

        province_destination: "",
        city_destination: "",

        weight: "",
        courier: ""
      })

      /**
       * state cities origin
       */
      const cities_origin    = ref({}) 

      /**
       * state cities destination
       */
      const cities_destination    = ref({}) 

      /**
       * resulCost
       */
      const resultCost = ref(null)

      onMounted(() => {

        axios.get('http://localhost:8000/api/provinces').then(response => {
          provinces.value = response.data.data
        })
        .catch(error => {
          console.log(error.response.data)
        })

      })
      
      /**
       * function getCitiesOrigin
       */
      function getCitiesOrigin() {
        
        axios.get(`http://localhost:8000/api/cities/${state.province_origin}`).then(response => {
          cities_origin.value = response.data.data
        })
        .catch(error => {
          console.log(error.response.data)
        })

      }

      /**
       * function getCitiesDestination
       */
      function getCitiesDestination() {

        axios.get(`http://localhost:8000/api/cities/${state.province_destination}`).then(response => {
          cities_destination.value = response.data.data
        })
        .catch(error => {
          console.log(error.response.data)
        })

      }

      /**
       * function getCostOngkir
       */
      function getCostOngkir() {

        axios.post('http://localhost:8000/api/checkOngkir/', {

          //send data ke server laravel
          origin: state.city_origin,
          destination: state.city_destination,
          weight: state.weight,
          courier: state.courier

        }).then(response => {
          resultCost.value = response.data.data[0].costs
        })
        .catch(error => {
          console.log(error.response.data)
        })

      }

      return {
        provinces, state, cities_origin, cities_destination, getCitiesOrigin, getCitiesDestination, getCostOngkir, resultCost
      }

    }

  }
</script>

<style>
  body {
    background: lightgrey !important;
  }
</style>

Di atas, pertama kita import hook onMounted dan 2 reactivity API, yaitu : reactive dan ref dari Vue Js. onMounted sama dengan mounted, yaitu salah satu lifecycle hook yang ada di dalam Vue, karena kita menggunakan Composition API, maka kita tambahkan on di depannya.

Untuk reactive dan ref merupakan fitur baru di Vue 3 yaitu Reactivity API, dimana digunakan untuk membuat sebuah variable menjadi reaktif.

CATATAN:

Jika menggunakan reactivity API ref di dalam function setup, maka untuk set dan get data menggunakan single objek .value.

Tapi untuk menampilkan di template kita tidak perlu menggunakan .value.

import { onMounted, reactive, ref } from 'vue'

Selanjutanyam, kita juga import Axios, ini akan kita gunakan untuk melakukan HTTP request ke server.

import axios from 'axios'

Disini kita akan menggunakan Composition API, dimana semua kode vue yang kita tulis akan di letakkan di dalam method setup.

setup() {

	//kode vue dan logika aplikasi

}

Di dalam method setup, pertama kita buat sebuah state baru dengan nama provinces dan state ini menggunakan jenis reactivity API ref. Dimana state ini akan di assign data provinsi nantinya.

/**
* state province
*/
const provinces = ref({})

Setelah itu, kita buat beberapa state lagi, seperti province_origin, city_origin, province_destination, city_destination, weight dan courier. Dan state ini menggunakan jenis reactivity API reactive.

/**
* state ID for province and city
*/
const state = reactive({
        
  province_origin: "",
  city_origin: "",

  province_destination: "",
  city_destination: "",

  weight: "",
  courier: ""
})

Kemudian, kita buat 3 state lagi, yaitu cities_origin, cities_destination dan resultCost.

  • cities_origin - akan digunakan untuk menampung data kota/kabupaten asal
  • cities_destination - akan digunakan untuk menampung data kota/kabupaten tujuan
  • resultCost - digunakan untuk menampilkan hasil perhitungan biaya ongkos kirim

Setelah itu, kita panggil hook onMounted, dimana di dalam hook tersebut kita melakukan request ke server Laravel dengan endpoint : http://localhost:8000/api/provinces dan menggunakan method GET untuk mendapatkan data provinsi.

axios.get('http://localhost:8000/api/provinces')

Setelah data berhasil di dapatkan, maka akan di assign ke dalam state provinces.

axios.get('http://localhost:8000/api/provinces').then(response => {
   provinces.value = response.data.data // <-- assign response data ke state "provinces"
})

Di atas, karena state provinces menggunakan jenis ref, maka untuk set data-nya kita tambahkan single objek .value.

Setelah data berhasil di assign, sekarang kita bisa tampilkan di bagian template menggunakan directive v-for, kurang lebih seperti berikut ini :

<select class="w-full border bg-white rounded px-3 py-2 outline-none" @change="getCitiesOrigin" v-model="state.province_origin">
   <option class="py-1" v-for="province in provinces" :key="province.id" :value="province.province_id">{{ province.province }}</option>
</select>

Di atas, saat kita meilih select option, maka akan menjalankan event @change dan event tersebut di arahkan ke dalam method yang bernama getCitiesOrigin.

/**
* function getCitiesOrigin
*/
function getCitiesOrigin() {
        
        axios.get(`http://localhost:8000/api/cities/${state.province_origin}`).then(response => {
   	  cities_origin.value = response.data.data
   })
   .catch(error => {
      console.log(error.response.data)
   })

}

Di dalam method di atas, kita akan mencari data kota/kabupaten berdasarkan ID provinsi yang dikirim oleh select option di dalam state state.province_origin. Dan untuk destination kita juga menggunakan cara yang sama dengan yang sudah kita bahas di atas.

Dan sekarang, jika teman-teman perhatikan pada button CEK ONGKOS KIRIM, kita memberikan sebuah event @click yang mengarah ke dalam method yang bernama getCostOngkir.

/**
* function getCostOngkir
*/
function getCostOngkir() {

  axios.post('http://localhost:8000/api/checkOngkir/', {

    //send data ke server laravel
    origin: state.city_origin,
    destination: state.city_destination,
    weight: state.weight,
    courier: state.courier

  }).then(response => {
    resultCost.value = response.data.data[0].costs
  })
  .catch(error => {
    console.log(error.response.data)
  })

}

Di atas, kita melakukan send/mengirim request ke endpoint : http://localhost:8000/api/checkOngkir dengan menggunakan method POST, dimana kita juga mengirim beberapa data, seperti : origin, destination, weight dan courier.

Jika data berhasil di kirim, maka server Laravel akan mengembalikan nilai JSON yang berisi informasi data pengiriman dan akan di assign ke dalam state resultCost.

Dan untuk menampilkan di dalam template, kita menggunakan directive v-for, kurang lebih seperti berikut ini :

<div class="bg-white p-3 shadow-sm rounded">
<h4 class="text-xl pb-1">HASIL ONGKOS KIRIM</h4>
<hr class="border-2">
  <div class="mt-4" v-for="(value, index) in resultCost" :key="index">
    {{ value.service }} - {{ value.cost[0].value }} - {{ value.cost[0].etd }} Hari
    <hr>
  </div>
</div>

Langkah 3 - Uji Coba

Sekarang, silahkan buka http://localhost:8080, maka kurang lebih tampilannya seperti berikut ini :

Dan sekarang jika kita coba untuk menghitung biaya ongkos kirim, jika berhasil maka hasilnya seperti berikut ini :

Dan jika kita buka pada versi mobile, maka tampilannya juga akan responsive, kurang lebih seperti berikut ini :

Sampai disini pembahasan tentang mengintegrasikan Laravel, RajaOngkir, Vue Js dan Tailwind CSS, jika ada error atau problem, silahkan bisa bertanya melalui kolom komentar di bawah, atau bisa bertanya melalui group telegram dari SantriKoding : https://t.me/santrikoding.

Terima Kaish


INFO :


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