3

I have installed Node.js and now I want to run some mock API.

index.js:

const app = require('koa')()
const cors = require('koa-cors')
const logger = require('koa-logger')
const router = require('koa-router')()

function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min)) + min;
}

function getRandomDeliveryLocation() {
    let locs = [
        { lat: 22.319181, lng: 114.170008, address: 'Mong Kok' },
        { lat: 22.336093, lng: 114.155288, address: 'Cheung Sha Wan' },
        { lat: 22.335538, lng: 114.176169, address: 'Kowloon Tong' }
    ]

    return locs[ getRandomInt( 0, locs.length ) ]
}

function getRandomDeliveryDescription( index ) {
    if ( index % 3 === 0 ) {
        return 'Deliver documents to Andrio'
    }

    let desp = [
        'Deliver documents to Andrio',
        'Gift pets to Leviero',
        'Gift pets to Alan'
    ]
    return desp[ getRandomInt( 0, desp.length ) ]
}

function getRandomDeliveryItem( index ) {
    return {
            id: index,
            description: getRandomDeliveryDescription( index ),
            imageUrl: 'https://s3-ap-southeast-1.amazonaws.com/lalamove-mock-api/images/pet-'
+ getRandomInt( 0, 9 ) + '.jpeg',
            location: getRandomDeliveryLocation()
    }
}

function delay(sec) {
    return new Promise(r => setTimeout(r, sec * 1000))
}

router.get('/pets', function* () {

    let cap = 70
    let offset = parseInt( this.query.offset, 10 )
    let limit = parseInt( this.query.limit, 10 )
    if ( isNaN( offset ) || isNaN( limit ) || offset < 0 || limit < 0 ) {
        this.status = 400
        return
    }

    yield delay(getRandomInt(0, 5))
    if (!getRandomInt(0, 9)) {
        this.status = 500
        return
    }

    this.body = []
    for ( let i = offset; i < offset + limit && i < cap; i++ ) {
        this.body.push( getRandomDeliveryItem( i ) )
    }

})

app
    .use(logger())
    .use(cors())
    .use(router.routes())
    .use(router.allowedMethods())

app.listen(8080)
console.log('Mock server started at port 8080')

It gives me:

Not Found Error when opening the localhost:8080/pets.

Am I missing something and how to fix it?

2
  • Just to confirm, are you intentionally using the generator function in router definition? Commented Sep 15, 2018 at 13:16
  • @planet_hunter yes to get random items Commented Sep 15, 2018 at 13:19

1 Answer 1

1

You can use async/await instead of a generator function, which works with the code you've posted. Here's what that looks like (I've made additional changes to fix additional problems):

router.get('/pets', async function (ctx) {
    let cap = 70
    let offset = parseInt( ctx.request.query.offset, 10 )
    let limit = parseInt( ctx.request.query.limit, 10 )
    if ( isNaN( offset ) || isNaN( limit ) || offset < 0 || limit < 0 ) {
        ctx.response.status = 400
        return
    }

    await delay(getRandomInt(0, 5))
    if (!getRandomInt(0, 9)) {
        ctx.response.status = 500
        return
    }

    ctx.response.body = []
    for ( let i = offset; i < offset + limit && i < cap; i++ ) {
        ctx.response.body.push( getRandomDeliveryItem( i ) )
    }
})

The changes here are:

  1. Removed the * from function * to stop it from being a generator function.
  2. Changed to async function so that await can be used.
  3. Use await instead of yield to wait for your delay promise to resolve.
  4. Switch from this.query to ctx.request.query.
  5. Switch from this.status and this.body to ctx.response.status and ctx.response.body.
Sign up to request clarification or add additional context in comments.

3 Comments

Done you are Pro in node.js. Can you please explain me what had gone wrong?
Sorry that took so long, I made a few edits over time as I made a few typos and it was hard for you to keep up. The main problem was that you were using a generator function instead of either a promise-returning function or an async/await function. After that, you were using this which doesn't refer to anything inside that function. This is why we had to use ctx which has both the request and the response properties.
Guys checkout this repo, I just copied this asnwer and made work there. Hope it will help. repl.it/@ManojChalode/IndelibleFrayedBsddaemon working url - indeliblefrayedbsddaemon--manojchalode.repl.co/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.