PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, October 14, 2022

[FIXED] how to cast/parse Axios REST response field from string to Date within React?

 October 14, 2022     axios, fetch-api, react-hooks, reactjs, typescript     No comments   

Issue

What would be the easiest way to effectively "convert" (parse/cast) the Date strings from a REST API response to true Dates? So that after "setItems" is called the contents of "items" is correctly typed as per the "ItemsType". Is there an easy way to do this in TypeScript/javascript?

Code below. Currently when I call setItems everything remains as strings, even though I have called out the items variable should be of type "ItemsType[]", so I guess it's not as if typing the variable magically makes it happen, and in fact there is no error thrown.

type ItemsType = {
  id: number
  locationName: string
  checkinDate: Date
  checkoutDate: Date   // edited-this shoudl have been Date also
}

function App() {
  const [items, setItems] = useState<ItemsType[]>([])
  useEffect(() => {
    (async () => {
      try {
        const res = await axios.get(`https://localhost:7040/Tripstop`)
        const rawItems = await res.data
        setItems(typedItems)
      }
    )()
  }, [])

Sample incoming REST data:

enter image description here


Solution

You could always implement a generic Axios response transformer to decode anything that looks like a date.

For example, this creates an Axios instance that transforms any value with the word "date" in the key

const dateKeyRx = /date/i;

export const api = axios.create({
  baseURL: "http://localhost:7040/",
  transformResponse: (data) =>
    JSON.parse(data, (key, value) =>
      dateKeyRx.test(key) ? new Date(value) : value
    ),
});

But I'd be more inclined to create a service for retrieving and transforming specific responses. This would encapsulate your logic without exposing the specific implementation to any consumers.

For example

// svc/tripstop.ts

import axios from "axios";

interface ResponseItem {
  id: number;
  locationName: string;
  checkinDate: string;
  checkoutDate: string;
}

export interface ItemsType extends ResponseItem {
  checkinDate: Date;
  checkoutDate: Date;
}

export const getTripstop = async (): Promise<ItemsType[]> => {
  const { data } = await axios.get<ResponseItem[]>(
    "https://localhost:7040/Tripstop"
  );
  return data.map(({ checkinDate, checkoutDate, ...rest }) => ({
    ...rest,
    checkinDate: new Date(checkinDate),
    checkoutDate: new Date(checkoutDate),
  }));
};

Then you can use it in your React components

import { getTripstop } from "./svc/tripstop";

// ... snip

useEffect(() => {
  getTripstop().then(setItems).catch(console.error);
}, []);

You could still use the response transformer which would save you the extra .map() call

export const getTripstop = async () =>
  (await api.get<ItemsType[]>("/Tripstop")).data;


Answered By - Phil
Answer Checked By - Marie Seifert (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing