Smart fields not working

Hi,

I created a simple smart fiedl fullname for my users collection, and it’s not working.

Here is my model (I cleaned it just to be sure that the problem was not anywhere else):

const mongoose = require("mongoose");
const { collection } = require("forest-express-mongoose");

const schema = mongoose.Schema(
  {
    _id: String,
    firstname: String,
    lastname: String,
  },
  {
    timestamps: false,
  }
);

module.exports = mongoose.model("users", schema, "users");

collection("users", {
  fields: [
    {
      field: "fullname",
      type: "String",
      get: (user) => user.firstname + " " + user.lastname,
    },
  ],
});

Did I forget something? All my packages are up to date. I tried to manually remove .forestadmin-schema.json, but still not working. I don’t see any error on the page, but the field doesn’t appear.

Thanks!

Hi @Sylvain :wave: and welcome to our community.
I’m just trying to reproduce your issue but unfortunately I can’t reproduce.
Can you check the presence of this smart field in your .forestadmin-schema.json?

Hi @Arnaud_Moncel, thanks for your answer.

My smart field is not in .forestadmin-schema.json. I saw in another thread that remove it and then restart the project to re-generate it fixed the issue, but it not worked for me.

I update the packages quite frequently, and I remember it used to work a few months ago. Maybe I forgot something when I updated my packages?

I don’t think so if you doesn’t have any error on your server start.
What is your NODE_ENV?
After removed the .forestadmin-schema.json and restart your server the .forestadmin-schema.json is regenerated?
Do you have this kind of env var FOREST_DISABLE_AUTO_SCHEMA_APPLY set in your .env file?

Yes, the schema is regenerated but without my smart field.

Here is what my .env looks like, I don’t have the FOREST_DISABLE_AUTO_SCHEMA_APPLY var:

APPLICATION_HOST=http://localhost:3310
APPLICATION_PORT=3310
DATABASE_URL=mongodb://127.0.0.1/XX
DATABASE_SSL=true
DATABASE_ENCRYPT=false
AUTH_SECRET=XX
FOREST_ENV_SECRET=XX
FOREST_AUTH_SECRET=XX

My node version is 12.13.1

Have you got the same problem with another collection?

This is the only collection where I want to use smart fields. Just for the test, I tried with another collection, but still the same problem.

Just to clarify, what is the structure of your server?
You should have something like this
image
According to the documentation The smart fields should be declared in the forest folder to be handle by the .forestadmin-schema.json generation.
Let me know if it’s help.

Ok thanks, I didn’t saw that. I just changed the structure but it’s still not working, I don’t understand. My code is just a copy-paste from the doc (I just changed customers with users). .forestadmin-schema.json was regenerated but without my smart field.

Shared with CloudApp

Hello @Sylvain :wave:

May I see the content of your app.js and middlewares/forestadmin.js please ?

It looks like the /forest/**.js files are not taken into account, let’s figure out why.

Steve.

Hi @Steve_Bunlon thanks for your help

I think my middleware file is the problem. Here it is:

Shared with CloudApp

I changed it to exclude models, but maybe I did something wrong.

app.js : https://share.getcloudapp.com/yAub6OWD

Thanks for providing these files @Sylvain

I see a lot of changes have been performed here. Did you make all these changes to exclude some models ?

Steve.

Actually, this file didn’t change a lot since its first version. I created the project 10 months ago, and frequently updated the packages. Maybe I should have changed this file after an upgrade?

According to Gitlab, the only change I’ve made is add excludedModels: ["MixedContactCompany", "MixedContactContact"].

Thanks!

Ok, can you give me version of forest-express-mongoose package please ?

"chalk": "~4.1.0",
    "debug": "~4.1.1",
    "dotenv": "~8.2.0",
    "express": "~4.17.1",
    "forest-express-mongoose": "^6.3.6",
    "lumber-forestadmin": "^1.3.0",
    "mongoose": "~5.10.0",
    "require-all": "^3.0.0"

@Sylvain thanks for the info.

I see some code do not correspond to what I would expect for a v6.3.6 project.

When did you generate this project ? May I ask you the current version of lumber ? (please run lumber --version in command line tool)

Depending on your answers, I will guide you to make this work :+1:

Steve.

Thanks @Steve_Bunlon for the answer

As I said, I generated the project 10 month ago, and updated the packages frequently. That’s why there is some old code I guess…

lumber version: 2.4.0

Ok this is clear to me now.

First of all, if you are using the V6 packages, some things have been changed such as the way you need to initialise the forest-express-mongoose package. You can find more information of the breaking changes in this doc. Your current initialisation of the package causes the smart fields to not be taken into account. Upgrading the code to what you will find in the documentation will fix that (please note that Liana.init is now asynchrone, and that you can pass configDir: path.join(__dirname, '../forest'), directly from the init object).

I see you have installed the lumber-forestadmin package in your project, which is not needed anymore as you are running version 6 of the forest-express-mongoose package, you can remove it.

To help going to stability, let me paste you an example of a fresh new app.js file and middlewares/forestadmin.js file:

app.js:

const express = require('express');
const requireAll = require('require-all');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const cors = require('cors');
const jwt = require('express-jwt');
const morgan = require('morgan');
const {
  ensureAuthenticated,
  PUBLIC_ROUTES,
} = require('forest-express-mongoose');

const app = express();

app.use(morgan('tiny'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

let allowedOrigins = [/\.forestadmin\.com$/ , /localhost:\d{4}$/];

if (process.env.CORS_ORIGINS) {
  allowedOrigins = allowedOrigins.concat(process.env.CORS_ORIGINS.split(','));
}

app.use(cors({
  origin: allowedOrigins,
  allowedHeaders: ['Authorization', 'X-Requested-With', 'Content-Type'],
  maxAge: 86400, // NOTICE: 1 day
  credentials: true,
}));

app.use(jwt({
  secret: process.env.FOREST_AUTH_SECRET,
  credentialsRequired: false,
}));

app.use('/forest', (request, response, next) => {
  if (PUBLIC_ROUTES.includes(request.url)) {
    return next();
  }
  return ensureAuthenticated(request, response, next);
});

requireAll({
  dirname: path.join(__dirname, 'routes'),
  recursive: true,
  resolve: Module => app.use('/forest', Module),
});

requireAll({
  dirname: path.join(__dirname, 'middlewares'),
  recursive: true,
  resolve: Module => Module(app),
});

module.exports = app;

middlewares/forestadmin.js (with your excluded models already configured:

const chalk = require('chalk');
const path = require('path');
const Liana = require('forest-express-mongoose');
const mongoose = require('mongoose');

module.exports = async function (app) {
  app.use(await Liana.init({
    modelsDir: path.join(__dirname, '../models'),
    configDir: path.join(__dirname, '../forest'),
    envSecret: process.env.FOREST_ENV_SECRET,
    authSecret: process.env.FOREST_AUTH_SECRET,
    excludedModels: ['MixedContactCompany', 'MixedContactContact'],
    mongoose,
  }));

  console.log(chalk.cyan('Your admin panel is available here: https://app.forestadmin.com/projects'));
};

I hope this will help you out,

Keep me in touch !

Steve.

2 Likes

It works! Thank you for your help Steve, and sorry, I should have read the doc a little better…