Search code examples
javascriptnode.jsbabeljsjestjsredux-orm

Issue doing map and filter on Redux ORM QuerySet


I am doing the tutorial for redux-orm here I need to call map on a QuerySet instance within my test.

The original test in the repo is here

This is how I create the Todo:

const todoTags = 'testing,nice,cool'
const user = session.User.first()
const userId = user.getId()

const action = {
  type: CREATE_TODO,
  payload: {
    text: todoText,
    tags: todoTags,
    user: userId
  }
}

const { Todo, Tag, User } = applyActionAndGetNextSession(schema, state, action)

My code looks like this:

const newTodo = Todo.last()
console.log(newTodo.tags.forEach, newTodo.tags.map)
console.log('Print all tags')
newTodo.tags.forEach(tag => {
  console.log('Prints a tag')
  console.log(tag)
})

newTodo.tags.map(tag => {
  console.log('Prints a tag 2')
  console.log(tag)
  return tag
})

expect(newTodo.text).toEqual(todoText)
expect(newTodo.user.getId()).toEqual(userId)
expect(newTodo.done).toBeFalsy()
const newTodoTags = newTodo.tags.map(tag => tag.name)
console.log(newTodoTags)
expect(newTodoTags).toEqual(['testing','nice','cool'])

The Tag model looks like:

Tag.backend = {
  idAttribute: 'name'
}

I can retrieve the names, which happen to be ids for this model using

newTodo.tags.idArr

which is hacky and unacceptable.

The test fails and this is my console output for

console.log(newTodo.tags)

 //OUTPUT
 QuerySet {
   ...
   idArr: ['testing', 'nice', 'cool']
   ...
 }

console.log(newTodo.tags.forEach, newTodo.tags.map)

//OUTPUT
[ Function forEach] [Function map]

console.log(newTodo.tags.toRefArray())

//OUTPUT
[undefined, undefined, undefined]

console.log('Print all tags')
newTodo.tags.forEach(tag => {
  console.log('Prints a tag')
  console.log(tag)
})

newTodo.tags.map(tag => {
  console.log('Prints a tag 2')
  console.log(tag)
  return tag
})

//OUTPUT
Prints all tags

console.log(newTodo.tags.withModels)

//Output is a QuerySet

newTodo.tags.withModels.map(tag => {
  console.log('mapping over tag models')
  console.log(tag)
  return tag
}

In response to @markerikson comment:

case CREATE_TODO:
    const tags = payload.tags.split(',')
    const trimmed = tags.map(tag => tag.trim())
    trimmed.forEach(tag => Tag.create(tag))
    break

in the Tag model handles a string inside the reducer. Code for both the Todo and Tag is here


Solution

  • As I suggested in my comment: you're not creating the Tag instances properly. it looks like you're passing each individual tag string straight to Tag.create(), so that it's like Tag.create("testing"). Instead, you need to pass an object, like Tag.create({name : "testing"}).