mswjs / data

Data modeling and relation library for testing JavaScript applications.
https://npm.im/@mswjs/data
MIT License
823 stars 52 forks source link

Unable to create mock data: "getPrimaryKeyValue" is not a function #233

Closed ajiteshchhatani closed 2 years ago

ajiteshchhatani commented 2 years ago

Hi! I am playing around with msw and mswjs/data in a small react-app. I was successfully able to follow the documentation and create handlers for the msw and a small basic model using mswjs/data.

However the moment I try to generate some data based on the model I get an error in my React app which says

Uncaught TypeError: propertyDefinition.getPrimaryKeyValue is not a function which points to the generateUser() function that creates some data.

Code snippet as below

mocks/handlers.js

import { rest } from 'msw';
import { v4 as uuidv4 } from 'uuid';
import { factory, primaryKey } from '@mswjs/data';
import { faker } from '@faker-js/faker'

export const db = factory({
    user: {
        id: primaryKey(uuidv4()),
        userName: String
    }
})

const generateUser = () => {
    const firstName = faker.name.firstName();
    const lastName = faker.name.lastName();
    return {
        userName: `${firstName} ${lastName}`
    }
}

console.log(db.user.create(generateUser()));

export const handlers = [
    rest.get('/users', (req, res, ctx) => {
        return res(
            ctx.status(200),
            ctx.json(db.user.getAll())
        )
    })
]

mocks/browser.js

import { setupWorker } from 'msw';
import { handlers } from './handlers';

export const worker = setupWorker(...handlers)

My React app entry point

src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
if(process.env.NODE_ENV === 'development') {
  const { worker } = require('./mocks/browser')
  worker.start();
}
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

All packages msw and mswjs/data along with react have their latest versions.

Anything wrong with what I am doing? Any help would be appreciated as I've done everything I could and could not find a resolution.

kettanaito commented 2 years ago

Hi, @ajiteshchhatani. Thanks for reaching out.

I believe I know what the issue is, it's in the way you define primaryKey for the user model. The primaryKey function expects either a constructor (to infer the type) or a getter function. In contrast, you're passing a resolved value of calling uuidv4().

Here's how to represent your intention:

export const db = factory({
    user: {
-       id: primaryKey(uuidv4()),
+       id: primaryKey(uuidv4), // notice no parentheses
        userName: String
    }
})

You can see us showcasing how to use Faker in particular:

https://github.com/mswjs/data/blob/2639a1fc147dcf43e83bc7a65f150c8128a95e22/README.md?plain=1#L990

ajiteshchhatani commented 2 years ago

Hey @kettanaito thank you for this.

The solution worked. It was a mistake on my part. I didn't look at it close enough.

Apologies for opening this issue. Thank you once again.