Unexpected error in forest-express-sequelize

When loading a specific association table in my account, I’m seeing the error TypeError: Cannot read property 'startsWith' of undefined in the logs and the UI is telling me that the server encountered an error.

Expected behavior

Expected to see the list of items from my table called “Recommendation Contents”

Actual behavior

Failure Logs

[forest] 🌳🌳🌳  Unexpected error: Cannot read property 'startsWith' of undefined
TypeError: Cannot read property 'startsWith' of undefined
    at /Users/lucasbordignon/code/point-api/cms/Point Fitness Insights/node_modules/forest-express-sequelize/dist/services/query-builder.js:57:21
    at Array.filter (<anonymous>)
    at /Users/lucasbordignon/code/point-api/cms/Point Fitness Insights/node_modules/forest-express-sequelize/dist/services/query-builder.js:56:62
    at Array.forEach (<anonymous>)
    at QueryBuilder.getIncludes (/Users/lucasbordignon/code/point-api/cms/Point Fitness Insights/node_modules/forest-express-sequelize/dist/services/query-builder.js:52:8)
    at getRecords (/Users/lucasbordignon/code/point-api/cms/Point Fitness Insights/node_modules/forest-express-sequelize/dist/services/resources-getter.js:134:34)
GET /forest/recommendationContent?fields%5BexternalContent%5D=id&fields%5BrecommendationContent%5D=externalContent%2ClinkLabel%2Ctemplate&fields%5Btemplate%5D=id&page%5Bnumber%5D=1&page%5Bsize%5D=15&searchExtended=0&timezone=America%2FSao_Paulo 500 85 - 10.372 ms
[forest] 🌳🌳🌳  Unexpected error: Cannot read property 'startsWith' of undefined
TypeError: Cannot read property 'startsWith' of undefined
    at /Users/lucasbordignon/code/point-api/cms/Point Fitness Insights/node_modules/forest-express-sequelize/dist/services/query-builder.js:57:21
    at Array.filter (<anonymous>)
    at /Users/lucasbordignon/code/point-api/cms/Point Fitness Insights/node_modules/forest-express-sequelize/dist/services/query-builder.js:56:62
    at Array.forEach (<anonymous>)
    at QueryBuilder.getIncludes (/Users/lucasbordignon/code/point-api/cms/Point Fitness Insights/node_modules/forest-express-sequelize/dist/services/query-builder.js:52:8)
    at countRecords (/Users/lucasbordignon/code/point-api/cms/Point Fitness Insights/node_modules/forest-express-sequelize/dist/services/resources-getter.js:174:34)
GET /forest/recommendationContent/count?fields%5BrecommendationContent%5D=externalContent%2ClinkLabel%2Ctemplate&fields%5BexternalContent%5D=id&fields%5Btemplate%5D=id&searchExtended=0&timezone=America%2FSao_Paulo 500 85 - 3.219 ms

Context

Please provide any relevant information about your setup.

Hey @Lucas_Bordignon and welcome in our community :champagne: !

Hmm it seems you have a badly formatted query parameters. Could you please share the request with all its query parameters decoded: ON chrome go to the network tab and show the query string parameters :pray:

Thanks @vince for the quick response!

For sure, here it goes for both requests that the app is making to the server (shown in the logs)

1st

fields[externalContent]: id
fields[recommendationContent]: externalContent,linkLabel,template
fields[template]: id
page[number]: 1
page[size]: 15
searchExtended: 0
timezone: America/Sao_Paulo

2nd

fields[recommendationContent]: externalContent,linkLabel,template
fields[externalContent]: id
fields[template]: id
searchExtended: 0
timezone: America/Sao_Paulo

On your model recommendationContent do you have any primary key ? It seems this is what is causing the issue

No, there’s no primary key there. The table is an association table, where it has two foreign keys and a simple text field

So I cannot have a model without a primary key to show in the app? Any possible workaround we could to achieve that?

Thanks in advance for the clarification!

To find the related data you must have an id. You have multiple solutions:

  • Add an autogenerated id column to your table
  • Add a composite primary key

Got it! Okay, so now I’ve created a primary key constraint with both fields now and I see that when accessing the database client, but still see the same error. I assume is my mistake in setting that up on the Lumber model definition

Could you give me guidance on how to add the constraint at the model?

I tried the following two approaches already

  1. Add the .belongsToMany() at the associated models
  2. Add the indexes key in my RecommendationContent model

But the error still happen in both scenarios, might be missing something that I couldn’t find in the docs

Hi @Lucas_Bordignon,

Could you please share with us the model definitions of th models that originated the issue?

Thank you :pray:

Hey @lamatt_v!

Sure, here is the definition for the Forest model

module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const RecommendationContent = sequelize.define(
    'recommendationContent',
    {
      linkLabel: {
        type: DataTypes.STRING,
        allowNull: false,
      },
    },
    {
      tableName: 'recommendation_content',
      timestamps: false,
      schema: process.env.DATABASE_SCHEMA,
      indexes: [
        {
          fields: ['templateId', 'externalContentId'],
          unique: true,
        },
      ],
    },
  )
  RecommendationContent.removeAttribute('id')
  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  RecommendationContent.associate = models => {
    RecommendationContent.belongsTo(models.externalContent, {
      foreignKey: {
        name: 'externalContentIdKey',
        field: 'externalContentId',
      },
      as: 'externalContent',
    })
    RecommendationContent.belongsTo(models.recommendationTemplates, {
      foreignKey: {
        name: 'templateIdKey',
        field: 'templateId',
      },
      as: 'template',
    })
  }

  return RecommendationContent
}

@Lucas_Bordignon,

Why did you have to had a RecommendationContent.removeAttribute('id')?

Also I generated on my end a project on a table having a composite primaryKey and the two target fields should be defines that way:

xId: {
  type: DataTypes.INTEGER,
  primaryKey: true,
  allowNull: false,
},
yId: {
  type: DataTypes.INTEGER,
  primaryKey: true,
  allowNull: false,
},

Could you try it?

1 Like

Thanks, @lamatt_v and @vince

The removeAttribute('id') was added from the auto-generated models that lumber created when first starting the server

The issue was really the missing primaryKey fields at both columns. After adding that I was able to see and edit the entries in the app!

Thank you both for the help!

1 Like