Expected 'property' to be of type string, instead found type object - Dynamoose

Viewed 2554

I am working with AWS DynamoDB and Dynamoose trying to fetch records using Scan function, but facing an issue that is not recognizable for me.

Stragenly, it's able to fetch records from another table in the same way and successfully get the records.

Here's my Code:

const vehicleMasterSchema = new dynamoose.Schema({
    "id": String,
    "customer_account_number": String,
    "fuel_type": String,
    "make": String,
    "model": String,
    "odometer_gatex": String,
    "plate_no": String,
    "rfid_gatex": String,
    "sales_agreement_id": String,
    "vehicle_category": String,
    "vehicle_id": String,
}, {
    "timestamps": {
        "createdAt": "create_date",
        "updatedAt": null // updatedAt will not be stored as part of the timestamp
    }
});
const vehicleMasterModel = dynamoose.model("vehicle_master", vehicleMasterSchema, { "create": false });

router.post('/getFuelingStatus', (req, res) => {
    var companyInfo = req.body;
    try {
        console.log(typeof vehicleMasterModel);
        vehicleMasterModel.scan("customer_account_number").eq(companyInfo.customerId).exec((error, results) => {
            if (error) {
                console.error(error);
            } else {
                res.json(results);
            }
        });
    } catch (error) {
        res.json(error);
    }
});

The TypeMismatch error is coming up only for this model same code is working for the other table.

Console Error

console error

My Table

table data

This appears to be related to this github issue on Dyanmoose

3 Answers

My guess is that the problem could be related with the name of your attribute, model.

In fact, this is the actual case: the following code, extracted from the source code in Document.ts is the one which is overwriting your model property:

Object.defineProperty(this, "model", {
  "configurable": false,
  "value": model
});

This is how the Document looks like before:

document before

And after the execution of the aforementioned code:

document after

This code is executed when processing the Scan exec function in DocumentRetriever.ts when the library maps every Item returned by DynamoDB to their internal Document representation, exactly in this line of code:

const array: any = (await Promise.all(result.Items.map(async (item) => await new this.internalSettings.model.Document(item, {"type": "fromDynamo"}).conformToSchema({"customTypesDynamo": true, "checkExpiredItem": true, "saveUnknown": true, "modifiers": ["get"], "type": "fromDynamo"})))).filter((a) => Boolean(a));

The error you reported is a consequence of that change when the type of the returned Item is checked against your schema model in the checkTypeFunction:

const {isValidType, matchedTypeDetails, typeDetailsArray} = utils.dynamoose.getValueTypeCheckResult(schema, value, genericKey, settings, {"standardKey": true, typeIndexOptionMap});
if (!isValidType) {
  throw new Error.TypeMismatch(`Expected ${key} to be of type ${typeDetailsArray.map((detail) => detail.dynamicName ? detail.dynamicName() : detail.name.toLowerCase()).join(", ")}, instead found type ${typeof value}.`);
...

Please, try a different name, I think it will work properly.

Schema must be like this :

const ImageGalleryFoldersSchema = new Schema({
  key: {
    type: String,
    hashKey: true,
    required: true,
  },
  displayName: {
    type: String,
    required: true,
  },
  parentFolderKey: {
    type: String,
    required: false,
  },
  isActive: {
    type: Boolean,
    default: true,
    required: false,
  },
}, {
  timestamps: true,
});

Maybe your problem is caused due to asynchronous behaviour.

To be more specific, I think that by the time you call the "scan"-function-chain the body-request has not been finished. However, due to the nature of Hoisting, the object "companyInfo" was already being initialised before you enter the function-call.

Therefore, you may get the specified "TypeMismatch"-error.

Could you please try implementing the following async/await-structure and tell me if this helps:

router.post('/getFuelingStatus', async (req, res) => {
    var companyInfo = await req.body;
    try {
        console.log(typeof vehicleMasterModel);
        vehicleMasterModel.scan("customer_account_number").eq(companyInfo.customerId).exec((error, results) => {
            if (error) {
                console.error(error);
            } else {
                res.json(results);
            }
        });
    } catch (error) {
        res.json(error);
    }
});
Related