Mengirim dan menerima data dengan SolidJS
mrfdn.com – Saat ini saya sedang belajar Solidjs.
Di sini saya ingin mengirim dan mengambil data dari Google Sheet.
Saya menggunakan Astro, dan menjalankan SolidJS sebagai bagiannya.
Bagian yang saya buat ini digunakan untuk mengirimkan salam/saran untuk undangan online.
Disini saya dibantu oleh ChatGPT untuk melakukan coding JS yang solid.
Berikut cara melakukannya dengan cepat:
Instal paket solidjs#
Pastikan Anda telah berhasil menginstal program Astro
Pengaturan baru Astro akan diperbarui ke file astro.config.mjs
desain file#
Sekarang kita perlu membuat file berikut:
src/
├── pages
│ ├── index.astro
└── solid
├── app.jsx
└── form.jsx
Saham tetap disimpan dalam arsip /src/solid/.
Buat objek SolidJS utama: App.jsx#
// App.jsx
import { createSignal, onCleanup } from 'solid-js';
import KonfirmasiHadir from './form.jsx';
// Define the URL of the CSV endpoint
const csvEndpoint = "https://docs.google.com/spreadsheets/d/asdfasdfadsfak/export?format=csv";
// SolidJS component
function App() {
// State to hold the JSON data
const [jsonData, setJsonData] = createSignal(null);
// Function to fetch CSV data and convert it to JSON
async function fetchAndConvert() {
try {
// Make an HTTP request to the CSV endpoint using the built-in fetch function
const response = await fetch(csvEndpoint);
// Check if the request was successful (status code 200)
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// Get the CSV data as text
const csvData = await response.text();
// Parse CSV text directly (replace with your own CSV parsing logic)
const jsonArray = parseCsvText(csvData);
// Process the resulting JSON array
console.log(jsonArray);
// Update the component state with the JSON data
setJsonData(jsonArray);
} catch (error) {
console.error('Error fetching or converting data:', error.message);
}
}
// Callback function to be passed to KonfirmasiHadir component
const handleDataSubmitted = () => {
// Fetch data in App component when form is submitted
fetchAndConvert();
};
// Function to parse CSV text into a JSON array
function parseCsvText(csvText) {
// Replace this logic with your own CSV parsing implementation
const lines = csvText.split('\n');
const headers = lines[0].split(',');
const jsonArray = [];
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split(',');
const entry = {};
for (let j = 0; j < headers.length; j++) {
entry[headers[j]] = values[j];
}
jsonArray.push(entry);
}
return jsonArray;
}
// Fetch data when the component mounts
fetchAndConvert();
// Cleanup function to cancel any ongoing fetch when the component unmounts
onCleanup(() => {
// Any cleanup logic, e.g., cancelling ongoing requests
});
// Render the component
return (
<div>
{jsonData() ? (
// Render your JSON data as needed
<>
<KonfirmasiHadir onDataSubmitted={handleDataSubmitted} />
<ul style="padding:0;">
{jsonData().map((item, index) => (
<li style="list-style:none;" key={index}>
<p style="font-weight:bold;">{item.nama}</p>
<i>{item.pesan}</i>
<hr/>
</li>
))}
</ul>
</>
) : (
// Render a loading indicator or other UI while fetching data
<p>Loading...</p>
)}
</div>
);
}
export default App;
Buat komponen Form.jsx#
import { createSignal } from 'solid-js';
function KonfirmasiHadir({ onDataSubmitted }) {
const [hadirChecked, setHadirChecked] = createSignal(false);
const [loading, setLoading] = createSignal(false);
const [formSubmitted, setFormSubmitted] = createSignal(false);
const scriptURL = 'https://script.google.com/macros/s/asdfasdgasdfagasdf/exec';
const handleSubmit = async (event) => {
event.preventDefault();
setLoading(true);
try {
const form = event.target;
const formData = new FormData(form);
const response = await fetch(scriptURL, { method: 'POST', body: formData });
if (response.ok) {
console.log('Success!', response);
setFormSubmitted(true);
// Reset the form
form.reset();
// Trigger the callback function
if (onDataSubmitted) {
onDataSubmitted();
}
} else {
console.error('Error!', response.statusText);
}
} catch (error) {
console.error('Error!', error.message);
} finally {
setLoading(false);
}
};
const handleHadirChange = () => {
setHadirChecked(!hadirChecked());
};
return (
<form class="" name="submit-form" onSubmit={handleSubmit} >
<label class="">
Nama lengkap
<input
name="nama"
type="text"
class=""
required
/>
</label>
<div class="my-6">
<label for="hadir" class="">
<input
type="radio"
id="hadir"
name="konfirmasi"
value="yes"
checked={hadirChecked()}
onChange={handleHadirChange}
class="text-black"
required
/>
Ya, saya akan datang
</label>
<label for="tidakhadir" class="block font-bold">
<input
type="radio"
id="tidakhadir"
name="konfirmasi"
value="no"
checked={!hadirChecked()}
onChange={handleHadirChange}
class="text-black"
required
/>
Tidak, saya tidak bisa datang
</label>
</div>
<div id="hadirberapa" style={{ display: hadirChecked() ? "block" : "none" }} class="block font-bold">
<label for="floatingPassword" class="block font-bold">
Berapa orang?
<input
type="text"
inputmode="numeric"
pattern="[0-9]+"
name="jumlah"
class=""
/>
</label>
</div>
<div class="">
<label for="ucapan" class="block font-bold">
Isi ucapan
<input
name="pesan"
type="text"
class=""
/>
</label>
</div>
<button class={`bg-blue-400 ${loading() ? "hidden" : "block"} bg-white/20 p-4 font-bold`} type="submit" disabled={loading()}>
Kirim
</button>
<button class={`bg-red-400 ${loading() ? "" : "hidden"} bg-white/20 p-4 font-bold`}>Loading</button>
{/*<button
type="submit"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
disabled={loading()}
>
{loading() ? 'Loading...' : 'Kirim'}
</button>
{formSubmitted() && (
<p class="text-green-500 font-bold mt-4">Terima kasih, data Anda telah terkirim!</p>
)}*/}
</form>
);
}
export default KonfirmasiHadir;
Hubungi bagian di halaman astro: index.astro#
---
import App from "../solid/app.jsx";
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Komentar</title>
</head>
<body>
<App client:load />
</body>
</html>
Jangan lupa untuk mengaturnya client:load agar astro dapat memuat pekerjaan pada bagian tersebut.
Akhir#
Jadi, dalam skrip ini, setelah mengklik tombol kirim, datanya akan dikirim terlebih dahulu ke Google Sheet dan kemudian objek utama (App.jsx) akan mengambil data dari Google Sheet.
Semoga bermanfaat.
PakarPBN
A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.
In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.
The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.