2

This is my first time using Oak and Deno. I learn it from https://www.robinwieruch.de/deno-oak-rest-api and documentation. I want to use REST-API deno using this script (server.ts).

import { v4 } from 'https://deno.land/std/uuid/mod.ts';

import {
  Application,
  Router,
  helpers,
} from 'https://deno.land/x/oak/mod.ts';

interface User {
  id: string;
  username: string;
}

const users = new Map<string, User>();

users.set('1', {
  id: '1',
  username: 'Robin Wieruch',
});

users.set('2', {
  id: '2',
  username: 'Dave Davids',
});

interface Message {
  id: string;
  text: string;
  userId: string;
}

const messages = new Map<string, Message>();

messages.set('1', {
  id: '1',
  text: 'Hello World',
  userId: '1',
});

messages.set('2', {
  id: '2',
  text: 'By World',
  userId: '2',
});

const port = 8000;
const app = new Application();

const router = new Router();

router.get('/session', (ctx) => {
  ctx.response.body = users.get(ctx.state.me.id);
});

router.get('/users', (ctx) => {
  ctx.response.body = Array.from(users.values());
});

router.get('/users/:userId', (ctx) => {
  const { userId } = helpers.getQuery(ctx, { mergeParams: true });
  ctx.response.body = users.get(userId);
});

router.get('/messages', (ctx) => {
  ctx.response.body = Array.from(messages.values());
});

router.get('/messages/:messageId', (ctx) => {
  const { messageId } = helpers.getQuery(ctx, { mergeParams: true });
  ctx.response.body = messages.get(messageId);
});

router.post('/messages', async (ctx) => {
  const id = v4.generate();

  const {
    value: { text },
  } = await ctx.request.body();

  messages.set(id, {
    id,
    text,
    userId: ctx.state.me.id,
  });

  ctx.response.body = messages.get(id);
});

router.delete('/messages/:messageId', async (ctx) => {
  const { messageId } = helpers.getQuery(ctx, { mergeParams: true });

  const isDeleted = messages.delete(messageId);

  ctx.response.body = isDeleted;
});

app.use(async (ctx, next) => {
  ctx.state = { me: users.get('1') };

  await next();
});

app.use(router.allowedMethods());
app.use(router.routes());

app.addEventListener('listen', () => {
  console.log(`Listening on: localhost:${port}`);
});

await app.listen({ port });

After running it with deno run --allow-net --allow-read server.ts I get the following error:

$ deno run --allow-net --allow-read server.ts 
Check file:///home/astrid/git/javascript/deno/deno-oak-rest-api/server.ts
error: TS2339 [ERROR]: Property 'text' does not exist on type 'Promise<any> | Promise<URLSearchParams> | FormDataReader | Promise<string> | Promise<Uint8Array> | undefined'.
    value: { text },
             ~~~~
    at file:///home/astrid/git/javascript/deno/deno-oak-rest-api/server.ts:77:14

This are my version

$ deno --version
deno 1.3.3
v8 8.6.334
typescript 4.0.2

How to solve this error ?

astridx
  • 6,581
  • 4
  • 17
  • 35
  • Just heads up: If you would like to check this repo for deno rest api boilerplate: https://github.com/vicky-gonsalves/deno_rest – Vicky Gonsalves Sep 14 '20 at 08:33

2 Answers2

2

Was changed around #201

  • ctx.request.body() is no longer async so you can drop await
  • Now accepts argument for type of body
  • value is now a promise so needs to be awaited (which is what the ts issue highlights)

Not sure what body type you were using before but here are some usages in the latest version

// for JSON:
const { value } = ctx.request.body({ type: "json" });
const { text } = await value;

// for FormData:
const { value } = ctx.request.body({ type: "form-data" });
const formData = await value.read();
const { text } = formData.fields;

See https://github.com/oakserver/oak/issues/239

Robin Wieruch
  • 14,900
  • 10
  • 82
  • 107
0

Note : we can access parse data from request for JSON as

const result = ctx.request.body({ type: "json" });
const data = await result.value;
mabdullahse
  • 3,474
  • 25
  • 23