0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js×Laravel】StripeとPostgreSQLのデータを紐づけてTable一覧にする方法

Posted at

StripeとPostgreSQLに登録されているデータの紐づけ

image.png

Next.jsとLaravelとStripeを使って商品管理システムを作っている最中に、同じ商品をそれぞれ①Stripeと②PostgreSQLに登録しています。

しかも、①と②それぞれの商品IDが違うので、紐づけを行う必要があります。

このさき、商品の編集や削除といった機能を作るときにはStripe側の商品IDとPostgreSQL側の商品IDの対関係が必要だからです。

したがって、どのようにして異なる商品ID値を持った同じ商品をつもづけたのかを備忘録として残しておきます。

【手順】

■Stripe側から商品を全件数分取得する

frontend/app/products/getListProducts/page.tsx
    useEffect(() => {
        axios.get('http://localhost:8000/api/stripe/products')
            .then((response) => {
                setStripeProducts(response.data);
            });
    }, []);

■Laravel経由でPostgreSQLから商品を全件数分取得する

frontend/app/products/getListProducts/page.tsx
    useEffect(() => {
        axios.get('http://localhost:8000/api/readAllProducts')
            .then((response) => {
                setProducts(response.data);
            });
    }, []);

map関数とfind関数を使ってStripe側とPostgreSQL側の①商品名(ProductName)と②商品説明(Product Description)が同じかを判定して新規で定義した配列に詰める

frontend/app/products/getListProducts/page.tsx
    const mergeProductData = (stripeProducts: any[], products: any[]) => {
        return stripeProducts.map((stripeProduct) => {
            // PostgreSQLの商品からnameとdescriptionの両方で一致する商品を探す
            const matchedProduct = products.find(product =>
                product.name === stripeProduct.name &&
                product.description === stripeProduct.description
            );

            // `productId`をstripeProductに追加
            return {
                ...stripeProduct,
                productId: matchedProduct ? matchedProduct.productId : null, // 一致する場合は`productId`を追加
            };
        });
    }

上記の方法で、Stripe側とPostgreSQL側とのデータの紐づけができました。

page.tsx
'use client'
import { useEffect, useState } from "react"
import axios from "axios"
import Header from "../productsComponents/header/page";
import { useRouter } from "next/navigation";

export default function AllListProducts() {
    const router = useRouter();
    const [stripeProducts, setStripeProducts] = useState<any[]>([]); // Stripeからの製品
    const [products, setProducts] = useState<any[]>([]); // PostgreSQLからの製品
    const [newProduct, setNewProduct] = useState({
        name: '',
        description: '',
        price: 0
    });

    // Stripeからの商品データを取得
    useEffect(() => {
        axios.get('http://localhost:8000/api/stripe/products')
            .then((response) => {
                setStripeProducts(response.data);
            });
    }, []);

    // PostgreSQLからの商品データを取得
    useEffect(() => {
        axios.get('http://localhost:8000/api/readAllProducts')
            .then((response) => {
                setProducts(response.data);
            });
    }, []);

    // 商品IDをStripe商品に追加する処理(name と description 両方を使って関連付け)
    const mergeProductData = (stripeProducts: any[], products: any[]) => {
        return stripeProducts.map((stripeProduct) => {
            // PostgreSQLの商品からnameとdescriptionの両方で一致する商品を探す
            const matchedProduct = products.find(product =>
                product.name === stripeProduct.name &&
                product.description === stripeProduct.description
            );

            // `productId`をstripeProductに追加
            return {
                ...stripeProduct,
                productId: matchedProduct ? matchedProduct.productId : null, // 一致する場合は`productId`を追加
            };
        });
    }

    // 両方のデータを結びつけて、productIdを追加した結果を取得
    const mergedProducts = mergeProductData(stripeProducts, products);

    // 商品編集ボタンのクリックハンドラー
    const clickProductEdit = () => {
        router.push(`/products/editProduct`);
    }

    // 商品削除ボタンのクリックハンドラー
    const clickProductDelete = () => {
        router.push('');
    }

    return (
        <div className="">
            <Header />
            <h1 className="font-bold">Product List</h1>
            <table className="w-full table-auto border border-gray-500 rounded-md">
                <thead className="bg bg-gray-100">
                    <tr>
                        <th className="p-4">ID</th>
                        <th className="p-4">Name</th>
                        <th className="p-4">Description</th>
                        <th className="p-4">
                            Price
                            <small>(USD)</small>
                        </th>
                        <th>Image</th>
                        <th>Edit</th>
                        <th>Delete</th>
                    </tr>
                </thead>
                <tbody>
                    {mergedProducts.length > 0 ? (
                        mergedProducts.map((product) => (
                            <tr key={product.id}>
                                <td className="p-4">{product.id}</td>
                                <td className="p-4">{product.name}</td>
                                <td className="p-4">{product.description}</td>
                                <td className="p-4">{product.price}</td>
                                <td className="p-4">
                                    {product.images ? (
                                        <img src={product.images[0]} style={{ width: 100 }} />
                                    ) : null}
                                </td>
                                <td className="p-4">
                                    <button
                                        type="button"
                                        className="bg bg-blue-500 text-white rounded-md px-4 py-4"
                                        onClick={clickProductEdit}
                                    >
                                        Edit
                                    </button>
                                </td>
                                <td className="p-4">
                                    <button
                                        type="button"
                                        className="bg bg-rose-500 text-white rounded-md px-4 py-4"
                                        onClick={clickProductDelete}
                                    >
                                        Delete
                                    </button>
                                </td>
                            </tr>
                        ))
                    ) : (
                        <tr>
                            <td colSpan={7} className="text-center p-4">
                                <p>Products are not register</p>
                            </td>
                        </tr>
                    )}
                </tbody>
            </table>
        </div>
    )
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?