[BUG] - Unable to set nested array attribute as a non required property
Summary:
I have a schema with an attribute of nested array containing external schema (field name is "teams"). I want to allow support for cases that there is no value to the attribute - in the form of blank array , null , empty attribute etc.
havent found a solution yet.
when trying to store an empty array, getting the following error:
"teams.0.name is a required property but has no value when trying to save document"
when trying to set the propery in the schema to {required: false}, and not passing any value as the prop, getting the following error:
"TypeError: node.forEach is not a function"
seems like it is always trying to scan through the array, also if it isnt required.
please help me to find a solution...
thanks in advance !
Code sample:
Schema
const innerTeamSchema = new dynamoose.Schema({
name: { type: String, required: true },
ref: { type: String, required: true },
isPro: {
type: Boolean,
default: false
},
profileImageURL: {
type: String,
validate(value) { return validator.isURL(value.toString()) }
},
isManager: {
type: Boolean,
default: false
}
}, { saveUnknown: false })
const schema = new dynamoose.Schema({
PK: {
type: String,
hashKey: true,
required: true,
set(original) { return setKeys(ModelNames.PLAYERS, original.toString(), true) }
},
SK: {
type: String,
rangeKey: true,
required: true,
set(original) { return setKeys(ModelNames.PLAYERS, original.toString(), false) }
},
teams: { // nested array field
type: Array,
schema: [innerTeamSchema],
required: false,
}
}
, {
timestamps: true,
saveUnknown: false
})
Code sample
const func = async () => {
try {
const player1 = new Player({
PK: "shir@[email protected]",
SK: "Profile",
teams: [] // trying to save with a blank array
})
console.log(await player1.save()) // throws the following error: TypeError: node.forEach is not a function
const player2 = new Player({ // trying to save without the team property (it isnt required)
PK: "shir@[email protected]",
SK: "Profile",
})
console.log(await player2.save()) // throws the following error: TypeError: node.forEach is not a function
} catch (e) {
console.log(e)
}
}
func()
error stack trace
TypeError: node.forEach is not a function
at D:\Users\USER\Documents\projects\mobile\full-stack\streetPro\StreetPro-BE\node_modules\dynamoose\lib\Document.ts:277:10
at Array.forEach (<anonymous>)
at traverse (D:\Users\USER\Documents\projects\mobile\full-stack\streetPro\StreetPro-BE\node_modules\dynamoose\lib\Document.ts:271:25)
at D:\Users\USER\Documents\projects\mobile\full-stack\streetPro\StreetPro-BE\node_modules\dynamoose\lib\Document.ts:287:5
at Array.forEach (<anonymous>)
at traverse (D:\Users\USER\Documents\projects\mobile\full-stack\streetPro\StreetPro-BE\node_modules\dynamoose\lib\Document.ts:271:25)
at Function.Document.attributesWithSchema (D:\Users\USER\Documents\projects\mobile\full-stack\streetPro\StreetPro-BE\node_modules\dynamoose\lib\Document.ts:293:2)
at Function.Document.objectFromSchema (D:\Users\USER\Documents\projects\mobile\full-stack\streetPro\StreetPro-BE\node_modules\dynamoose\lib\Document.ts:383:4)
at Document.toDynamo (D:\Users\USER\Documents\projects\mobile\full-stack\streetPro\StreetPro-BE\node_modules\dynamoose\lib\Document.ts:519:17)
at async Promise.all (index 0)
dynamoose version : 2.7.3
Other:
- [x] I have read through the Dynamoose documentation before posting this issue
- [x] I have searched through the GitHub issues (including closed issues) and pull requests to ensure this issue has not already been raised before
- [x] I have searched the internet and Stack Overflow to ensure this issue hasn't been raised or answered before
- [x] I have tested the code provided and am confident it doesn't work as intended
- [x] I have filled out all fields above
- [x] I am running the latest version of Dynamoose
can someone please try to help me out here ? im trying to figure it out for a couple of days and doesnt manage to find a solution... @fishcharlie
@idangabbay564 Hoping to find time to look at this today or tomorrow. No guarantees tho. Been super busy lately.
@idangabbay564 I was able to reproduce this. From what I can see right now, it does look like a bug.
My only workaround I can provide right now is to use saveUnknown and remove the teams property from your schema.
Hopefully I'll get around to fixing this soon, in the meantime if you wanna try to look at creating a PR that would be appreciated as well.
Note to self, below is an example to reproduce this:
const dynamoose = require("dynamoose");
(async () => {
const innerTeamSchema = new dynamoose.Schema({
name: { type: String, required: true },
ref: { type: String, required: true },
isPro: {
type: Boolean,
default: false
},
profileImageURL: {
type: String,
// validate(value) { return validator.isURL(value.toString()) }
},
isManager: {
type: Boolean,
default: false
}
}, { saveUnknown: false })
const schema = new dynamoose.Schema({
PK: {
type: String,
hashKey: true,
required: true,
// set(original) { return setKeys(ModelNames.PLAYERS, original.toString(), true) }
},
SK: {
type: String,
rangeKey: true,
required: true,
// set(original) { return setKeys(ModelNames.PLAYERS, original.toString(), false) }
},
teams: { // nested array field
type: Array,
schema: [innerTeamSchema],
required: false,
}
}, {
timestamps: true,
saveUnknown: false
})
dynamoose.aws.ddb.local();
const Player = dynamoose.model("Player" + Date.now(), schema);
// const player1 = new Player({
// PK: "shir@[email protected]",
// SK: "Profile",
// teams: [] // trying to save with a blank array
// });
// console.log(await player1.save()) // throws the following error: ValidationError: teams.0.name is a required property but has no value when trying to save document
const player2 = new Player({ // trying to save without the team property (it isnt required)
PK: "shir@[email protected]",
SK: "Profile",
})
console.log(await player2.save()) // throws the following error: TypeError: node.forEach is not a function
})();
hey @fishcharlie have you managed to find a solution ? tryed to look into the code and didnt go well...
@idangabbay564 Not yet. Still on my todo list. I was out of town all last week. Hoping to make time soon.
hey @fishcharlie have you managed to look at the bug ?
Any update?
Hi,
i ran into the same error. The problem is the default-value for your properties "isPro" and "isManager" in your innerTeamSchema. If you try to save your player2 with an empty teams-array, the teams-array is not empty for dynamoose because the object to save looks something like this:
{
"PK": "shir@[email protected]",
"SK": "Profile",
"teams": [
{
"isPro": false,
"isManager": false
}
]
}
Because the "name"-property in your innerTeamSchema is required an error is thrown.
As a workaround, I would recommend deleting the default values from your innerTeamSchema and assigning a default value programmatically.
Kind regards
Any updates on this? We're running into this, but don't have default values in the nested schema.
@slushman No updates. We use the 👍 voting system on the original issue to mark interest and priority. Currently this issue only has 1 👍 up vote. So its priority is fairly low.
PRs are welcome as always.
But in the meantime, there is a workaround by using saveUnknown, and it looks like the previous comment also mentioned removing the default value.
Any updates on this issue will be posted here.