0

I have been trying to use a map to store the responses of proxies from two different providers to make it easier to look them up as they would be stored in a hash-map. For example:

let proxies = new Map<String, Pod[]>();
proxies.get("my-provider");

However when I try to render the data to the page using a react useState hook with typescript, apparently the types differ. My type definition is as follows:

export interface Pod {
  pod: number;
  timestamp: string; <- ISO UTC timestamp
  status: string; <-- 200 OK, 4xx, 5xx etc.
}

export interface PodProvider {
  provider: {
    [key: string]: Pod[]; <- indexed map containing a list
  }
}

I have a useEffect hook that calls a method to probe the proxies when the component has loaded and then adds the responses to the hashmap along with a unique key to identify the provider of said proxies as follows:

const [response, setResponse] = useState<Map<String, Pod[]>>();

useEffect(() => {
  const goProbe = async () => {
    const results = await probe(provider1Proxies);
    proxies.set("provider1", results);
    setResponse(proxies);
  }
  goProbe();
}, []);

Lastly, the logic for how to render the state to the DOM is provided in a separate component like this:

export const Logger: React.FC<PodProvider> = ({ provider }, identifier: string) => ( <- notice the type used here
  <React.Fragment>
    <Table size="small">
      <Caption>
        <XL>Log Output</XL>
      </Caption>
      <Head>
        <HeaderRow>
          <HeaderCell>Timestamp</HeaderCell>
          <HeaderCell>Pod</HeaderCell>
          <HeaderCell>Status</HeaderCell>
        </HeaderRow>
      </Head>
      <Body>
        {
          provider[identifier].flatMap((response, key) => {
            return (
              <Row key={key}>
                <Cell>{response.pod}</Cell>
                <Cell>{response.status}</Cell>
                <Cell>{response.timestamp}</Cell>
              </Row>
            );
          })
        }
      </Body>
    </Table>
  </React.Fragment>
);

My question is what did I do wrong? Why are Map<String, Pod[]> and '{ [key: string]: Pod[]; } different? How to fix the code to do as expected?

Thanks :)

  • They are different because they are different types (Map has methods such as `get` and `set` which an indexer doesn't). Why can't you just define `provider` as `Map`? – Nadia Chibrikova Jul 25 '21 at 14:54
  • @NadiaChibrikova Thanks for the comment but can you clarify what you mean by "Why can't you just define provider as Map". –  Jul 25 '21 at 20:09
  • I mean why don't you replace `provider:{ [key: string]: Pod[]; }` in `interface PodProvider` with `provider:Map` which will more accurately reflect its actual type? – Nadia Chibrikova Jul 25 '21 at 21:00
  • @NadiaChibrikova Thanks for the clarification, I'm still learning the types to typescript. I've a new issue now `Type 'Map | undefined' is not assignable to type 'Map'.` The Map would have a value at build so how to remove undefined? What do you suggest? –  Jul 26 '21 at 09:03
  • It picks up the initial value that you pass to `useState`, which is `undefined` as you don't pass anything. Try `useState>(new Map());` instead – Nadia Chibrikova Jul 26 '21 at 09:28
  • @NadiaChibrikova Thank you! That worked. To avoid asking questions like this in the future may I ask how you learned typescript and any resources that you found useful? –  Jul 26 '21 at 09:40
  • If you can get through the official docs you'll definitely learn all you need to know (https://www.typescriptlang.org/docs/handbook/intro.html), alternatively you can take a free course offered by Microsoft (https://learn.microsoft.com/en-us/learn/paths/build-javascript-applications-typescript/) I did the course, then did a couple of projects using TS and working with the docs for reference. Hope it helps! – Nadia Chibrikova Jul 26 '21 at 21:33

0 Answers0