parseAtom generic function, move to lib

This commit is contained in:
Devin Deng 2022-11-06 18:23:09 -08:00
parent 398ce7b727
commit d4dda9affa
3 changed files with 56 additions and 26 deletions

36
lib/parseAtomToJSON.ts Normal file
View file

@ -0,0 +1,36 @@
import { PrimitiveAtom, Getter } from "jotai";
export const parseAtomToJSON = <T extends PrimitiveAtom<any>, K extends any>(atomToParse: T, get: Getter): K => {
const getAtomValue = get(atomToParse);
if (getAtomValue instanceof Array) {
return parseAtomArrayToJSON(getAtomValue, get) as K;
}
if (getAtomValue instanceof Object) {
return parseAtomObjectToJSON(atomToParse as PrimitiveAtom<Object>, get) as K;
}
return getAtomValue as K;
}
const parseAtomObjectToJSON = <T extends PrimitiveAtom<Object>>(atomObject: T, get: Getter) => {
const parsed = {} as Record<string, unknown>;
const getAtomObject = get(atomObject) as Record<string, PrimitiveAtom<unknown>>;
const itemKeys = Object.keys(getAtomObject);
itemKeys.forEach((key) => {
const atomValueToParse = getAtomObject[key];
parsed[key] = parseAtomToJSON(atomValueToParse, get);
})
return parsed;
}
const parseAtomArrayToJSON = <T extends PrimitiveAtom<unknown>[]>(atomArray: T, get: Getter) => {
return atomArray.map((atomElement) => parseAtomToJSON(atomElement, get));
}

View file

@ -2,11 +2,23 @@ import { atom, PrimitiveAtom } from "jotai";
import { SetAtom } from "jotai/core/atom"; import { SetAtom } from "jotai/core/atom";
import { IPerson } from "../components/Person"; import { IPerson } from "../components/Person";
import { IReceiptItem, Receipt } from "../components/ReceiptItem"; import { IReceiptItem, Receipt } from "../components/ReceiptItem";
import { parseAtomToJSON } from "./parseAtomToJSON";
import parseInput from "./parseInput"; import parseInput from "./parseInput";
export const totalAtom = atom(0); export const totalAtom = atom(0);
export const receiptAtom = atom<PrimitiveAtom<IReceiptItem>[]>([]); export const receiptAtom = atom<PrimitiveAtom<IReceiptItem>[]>([]);
export const receiptAtomToJSON = atom((get) => {
const receiptJSON: any[] = [];
const receipt = get(receiptAtom);
for (const itemAtom of receipt) {
receiptJSON.push(parseAtomToJSON(itemAtom, get));
}
return receiptJSON;
});
export const receiptTotalAtom = atom((get) => { export const receiptTotalAtom = atom((get) => {
const totalValue = get(totalAtom); const totalValue = get(totalAtom);
const receipt = get(receiptAtom); const receipt = get(receiptAtom);

View file

@ -1,17 +1,19 @@
import { useAtom, atom } from "jotai"; import { useAtom, atom, PrimitiveAtom } from "jotai";
import type { NextPage } from "next"; import type { NextPage } from "next";
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
import { SyntheticEvent, useState } from "react"; import { SyntheticEvent, useState } from "react";
import { Form } from "react-bootstrap"; import { Form } from "react-bootstrap";
import NumberEditBox from "../components/NumberEditBox"; import NumberEditBox from "../components/NumberEditBox";
import ReceiptItem from "../components/ReceiptItem"; import ReceiptItem, { IReceiptItem } from "../components/ReceiptItem";
import { moneyFormatter } from "../lib/formatter"; import { moneyFormatter } from "../lib/formatter";
// import { parseAtomToJSON } from "../lib/parseAtomToJSON";
import { ParsedInputDisplay } from "../lib/parseInput"; import { ParsedInputDisplay } from "../lib/parseInput";
import { import {
addLine, addLine,
receiptAtom, receiptAtom,
receiptTotalAtom, receiptTotalAtom,
totalAtom, totalAtom,
receiptAtomToJSON,
} from "../lib/state"; } from "../lib/state";
const Home: NextPage = () => { const Home: NextPage = () => {
@ -19,30 +21,10 @@ const Home: NextPage = () => {
const [input, setInput] = useState(""); const [input, setInput] = useState("");
const [total] = useAtom(totalAtom); const [total] = useAtom(totalAtom);
const [calculated] = useAtom(receiptTotalAtom); const [calculated] = useAtom(receiptTotalAtom);
const [receiptJson] = useAtom(receiptAtomToJSON);
const isAddCalled = useRef(false); const isAddCalled = useRef(false);
const [receiptJson] = useAtom(
atom((get) => {
const receiptJson: any[] = [];
for (const itemAtom of receipt) {
const receiptItemFromAtom = get(itemAtom);
const splitBetweenArray = get(receiptItemFromAtom.splitBetween).map(
(personAtom) => ({
name: get(get(personAtom).name),
})
);
const receiptItemParsed = {
name: get(receiptItemFromAtom.name),
price: get(receiptItemFromAtom.price),
splitBetween: splitBetweenArray,
};
receiptJson.push(receiptItemParsed);
}
return receiptJson;
})
);
const formatter = new Intl.NumberFormat("en-US", { const formatter = new Intl.NumberFormat("en-US", {
style: "currency", style: "currency",
currency: "USD", currency: "USD",
@ -58,13 +40,13 @@ const Home: NextPage = () => {
}; };
const receiptJSONString = JSON.stringify(receiptJson); const receiptJSONString = JSON.stringify(receiptJson);
useEffect(() => { useEffect(() => {
const updateDb = async () => { const updateDb = async () => {
const response = await fetch("/api/createReceipt", { const response = await fetch("/api/updateReceipt", {
method: "POST", method: "POST",
body: JSON.stringify({ receipts: receiptJson }), body: JSON.stringify({ receipts: receiptJson }),
}); });
console.log(receiptJSONString);
}; };
if (isAddCalled.current) { if (isAddCalled.current) {