-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cant push array item that has .path() getter? #6637
Comments
@zhepa I'll take a look at this ASAP. In the meantime, you can add 6637.js#!/usr/bin/env node
'use strict';
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/gh-6637');
const conn = mongoose.connection;
const Schema = mongoose.Schema;
const schema = new Schema({
images: {
preview: String,
background: String,
gallery: {
type: [{
preview: String,
original: String
}]
}
}
});
const UPLOADS_BASE_URL = 'http://example.com/';
schema.path('images.preview').get(preview => UPLOADS_BASE_URL + preview);
schema.path('images.background').get(background => UPLOADS_BASE_URL + background);
schema.path('images.gallery').get(gallery => {
if (!gallery) { return undefined; }
return gallery.map(photo => {
return {
id: photo._id,
preview: UPLOADS_BASE_URL + photo.preview,
original: UPLOADS_BASE_URL + photo.original
};
});
});
const Test = mongoose.model('Excursion', schema, 'gh6637');
const test = new Test({
images: {
preview: 'preview.jpg',
background: 'background.png',
gallery: [
{ preview: 'preview1', original: 'original1' },
{ preview: 'preview2', original: 'original2' },
{ preview: 'preview3', original: 'original3' }
]
}
});
async function run() {
await conn.dropDatabase();
await test.save();
let doc = await Test.findOne();
console.log(doc.images.preview);
console.log(test.images.gallery);
return conn.close();
}
run(); Output:
|
@lineus try to test.images.gallery.push({ preview: 'preview4', original: 'original4' });
console.log(test.images.gallery); there is no problem with empty array i guess |
@zhepa in the process of adapting your example for this, when I would create a model instance the code would fail even before the save. Once I got that to work, I neglected to test |
I've been playing around with this some. Here's a minimal repro script: 6637.js#!/usr/bin/env node
'use strict';
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/gh6637', { useNewUrlParser: true });
const conn = mongoose.connection;
const Schema = mongoose.Schema;
const schema = new Schema({
nested: {
arr: [{ key: String }]
}
});
schema.path('nested.arr').get(function(v) {
return v.map(el => {
return {
key: 'foobar' + el.key,
};
});
});
const Test = mongoose.model('test', schema);
const test = new Test;
test.nested.arr.push({ key: 'value' });
test.nested.arr.push({ key: 'value2' });
async function run() {
await conn.dropDatabase();
await test.save();
let doc = await Test.findOne();
console.log(doc.nested.arr);
return conn.close();
}
run(); Output:
|
@zhepa while this is getting sorted out, here are a couple of possible ways around this based on my code above: One is a bit of a hack.if you change the getter to: schema.path('nested.arr').get(function(v) {
if (v.length > 1) {
return v.map(el => {
return {
key: 'foobar' + el.key,
};
});
} else {
return v;
}
}); the output becomes:
note if the array only contains one value, The second is more saneapply the getter to the subdoc schema explicitly: #!/usr/bin/env node
'use strict';
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/gh6637', { useNewUrlParser: true });
const conn = mongoose.connection;
const Schema = mongoose.Schema;
const subSchema = new Schema({
key: String
});
subSchema.path('key').get(function(v) {
return 'foobar' + v;
});
const schema = new Schema({
nested: {
arr: [subSchema]
}
});
const Test = mongoose.model('test', schema);
const test = new Test;
test.nested.arr.push({ key: 'value' });
test.nested.arr.push({ key: 'value2' });
async function run() {
await conn.dropDatabase();
await test.save();
let doc = await Test.findOne();
console.log(doc.nested.arr[0].key);
console.log(doc.nested.arr[1].key);
return conn.close();
}
run(); Output:
|
Upon more careful inspection, this is expected behavior. The below is how you do what you're trying to do: const subSchema = new Schema({
key: String
});
subSchema.path('key').get(function(v) {
return 'foobar' + v;
});
const schema = new Schema({
nested: {
arr: [subSchema]
}
}); Or: const schema = new Schema({
nested: {
arr: [{ key: String }]
}
});
schema.path('nested.arr.0.key').get(v => 'foobar' + v); When a getter returns an object, changes to that object do not get tracked because getters are designed to not modify the underlying document, just to transform the output. |
I have model
ExcursionModel.js
When i trying to add new
images.gallery
items by .push() method there is nothing changes in arrayBut when i modify
images.preview
orimages.background
everything works correctlyOnce i remove path getters, things getting normal
index.js
thanks in advance
Im using mongoose 5.1.7 & node 10.5.0
The text was updated successfully, but these errors were encountered: