Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[with-typescript] Updated TypeScript example to use API routes #9073

Merged
merged 3 commits into from
Oct 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/with-typescript/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const Layout: React.FunctionComponent<Props> = ({
<a>About</a>
</Link>{' '}
|{' '}
<Link href="/initial-props">
<a>With Initial Props</a>
<Link href="/users">
<a>Users List</a>
</Link>
</nav>
</header>
Expand Down
2 changes: 1 addition & 1 deletion examples/with-typescript/components/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Props = {
}

const ListItem: React.FunctionComponent<Props> = ({ data }) => (
<Link href={`/detail?id=${data.id}`}>
<Link href="/users/[id]" as={`/users/${data.id}`}>
<a>
{data.id}: {data.name}
</a>
Expand Down
1 change: 1 addition & 0 deletions examples/with-typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"type-check": "tsc"
},
"dependencies": {
"isomorphic-unfetch": "3.0.0",
"next": "latest",
"react": "^16.10.1",
"react-dom": "^16.10.1"
Expand Down
18 changes: 18 additions & 0 deletions examples/with-typescript/pages/api/users/[id].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { sampleUserData } from '../../../utils/sample-data'

export default (req: NextApiRequest, res: NextApiResponse) => {
try {
const { id } = req.query;
const selected = sampleUserData.find(data => data.id === Number(id))

if (!selected) {
throw new Error('Cannot find user')
}

res.status(200).json(selected)
} catch (err) {
res.status(404).json({ statusCode: 404, message: err.message })
}
}

14 changes: 14 additions & 0 deletions examples/with-typescript/pages/api/users/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { sampleUserData } from '../../../utils/sample-data'

export default (_: NextApiRequest, res: NextApiResponse) => {
try {
if (!Array.isArray(sampleUserData)) {
throw new Error('Cannot find user data')
}

res.status(200).json(sampleUserData)
} catch (err) {
res.status(500).json({ statusCode: 500, message: err.message })
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as React from 'react'
import { NextPageContext } from 'next'
import Layout from '../components/Layout'
import { User } from '../interfaces'
import { findData } from '../utils/sample-api'
import ListDetail from '../components/ListDetail'

import { User } from '../../interfaces'
import Layout from '../../components/Layout'
import ListDetail from '../../components/ListDetail'
import { sampleFetchWrapper } from '../../utils/sample-api'

type Props = {
item?: User
Expand All @@ -14,7 +15,7 @@ class InitialPropsDetail extends React.Component<Props> {
static getInitialProps = async ({ query }: NextPageContext) => {
try {
const { id } = query
const item = await findData(Array.isArray(id) ? id[0] : id)
const item = await sampleFetchWrapper(`http://localhost:3000/api/users/${Array.isArray(id) ? id[0] : id}`)
return { item }
} catch (err) {
return { errors: err.message }
Expand All @@ -36,7 +37,7 @@ class InitialPropsDetail extends React.Component<Props> {

return (
<Layout
title={`${item ? item.name : 'Detail'} | Next.js + TypeScript Example`}
title={`${item ? item.name : 'User Detail'} | Next.js + TypeScript Example`}
>
{item && <ListDetail item={item} />}
</Layout>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { NextPage } from 'next'
import Link from 'next/link'
import Layout from '../components/Layout'
import List from '../components/List'
import { User } from '../interfaces'
import { findAll } from '../utils/sample-api'

import Layout from '../../components/Layout'
import List from '../../components/List'
import { User } from '../../interfaces'
import { sampleFetchWrapper } from '../../utils/sample-api'

type Props = {
items: User[]
pathname: string
}

const WithInitialProps: NextPage<Props> = ({ items, pathname }) => (
<Layout title="List Example (as Functional Component) | Next.js + TypeScript Example">
<h1>List Example (as Function Component)</h1>
<Layout title="Users List | Next.js + TypeScript Example">
<h1>Users List</h1>
<p>
Example fetching data from inside <code>getInitialProps()</code>.
</p>
<p>You are currently on: {pathname}</p>
<List items={items} />
<p>
Expand All @@ -24,10 +28,12 @@ const WithInitialProps: NextPage<Props> = ({ items, pathname }) => (
)

WithInitialProps.getInitialProps = async ({ pathname }) => {
// Example for including initial props in a Next.js function compnent page.
// Example for including initial props in a Next.js function component page.
// Don't forget to include the respective types for any props passed into
// the component.
const items: User[] = await findAll()
const items: User[] = await sampleFetchWrapper(
'http://localhost:3000/api/users'
)

return { items, pathname }
}
Expand Down
43 changes: 11 additions & 32 deletions examples/with-typescript/utils/sample-api.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,13 @@
import { User } from '../interfaces'

/** Dummy user data. */
export const dataArray: User[] = [
{ id: 101, name: 'Alice' },
{ id: 102, name: 'Bob' },
{ id: 103, name: 'Caroline' },
{ id: 104, name: 'Dave' },
]

/**
* Calls a mock API which finds a user by ID from the list above.
*
* Throws an error if not found.
*/
export async function findData(id: number | string) {
const selected = dataArray.find(data => data.id === Number(id))

if (!selected) {
throw new Error('Cannot find user')
}

return selected
}

/** Calls a mock API which returns the above array to simulate "get all". */
export async function findAll() {
// Throw an error, just for example.
if (!Array.isArray(dataArray)) {
throw new Error('Cannot find users')
import fetch from 'isomorphic-unfetch'

export async function sampleFetchWrapper(
input: RequestInfo,
init?: RequestInit
) {
try {
const data = await fetch(input, init).then(res => res.json())
return data
} catch (err) {
throw new Error(err.message)
}

return dataArray
}
9 changes: 9 additions & 0 deletions examples/with-typescript/utils/sample-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { User } from '../interfaces'

/** Dummy user data. */
export const sampleUserData: User[] = [
{ id: 101, name: 'Alice' },
{ id: 102, name: 'Bob' },
{ id: 103, name: 'Caroline' },
{ id: 104, name: 'Dave' },
]