yogiben / meteor-admin

A complete admin dashboard solution
https://atmospherejs.com/yogiben/admin
GNU General Public License v3.0
826 stars 261 forks source link

custom helper keeps returning same document #302

Open proletesseract opened 8 years ago

proletesseract commented 8 years ago

I'm using meteor-admin combined with meteor-collection-helpers to try and display a custom helper within the 'view all' view of my collection.

I have two collections; artists and artistImages. artistImages are linked to an artists with their _id. That works fine and I have the correct artists name displaying in my dropdown in the edit/new screen of artistImages. I want the artist's name to display in the 'view all' section of the artistImages collection against each row, but for some reason its always the first artists name which displays.

In my meteor-admin config file I have the collection setup like this:

...
ArtistImages: {
    tableColumns: [
        { label: 'ArtistId', name: 'artistId' },
        { label: 'Artist', name: function() {
                return ArtistImages.findOne().artist();
            }
        },
        { label: 'Image', name: 'image' },
    ]
},
...

Then inside my artistImages collection definition I have

ArtistImages = new Mongo.Collection("artist-images");

ArtistImages.helpers({
    artist: function() {
        var artist = Artists.findOne(this.artistId);
        if(artist){
            return artist.name;
        } else {
            return "(undefined)";
        }
    }
});

Schemas = {};

Schemas.ArtistImages = new SimpleSchema({
    artistId: {
        type: String,
        label: 'Artist',
        autoform: {
            options: function () {
                return _.map(Artists.find({}).fetch(), function (artist) {
                    return {
                        label: artist.name,
                        value: artist._id
                    };
                });
            }
        }
    },
    image: {
        type: String,
        label: 'Image',
        max: 200,
        optional: true
    },
    caption: {
        type: String,
        label: 'Caption',
        max: 120,
        optional: true
    }
});

ArtistImages.attachSchema(Schemas.ArtistImages);

However if i console.log this.artistId from within the artist() helper, its always returning the same id even if i have different artists assigned to each artist image.

view all:

screen shot 2015-11-21 at 1 58 59 pm

Notice the artistId is different but the name is the same, both names are for the artist in the first row.

Any suggestions? I'm stumped.

ShockiTV commented 8 years ago

ArtistImages.findOne() will always return same (first) document when you have more documents in minimongo. Use some _id there or some selector to get the one you want Or use that

name: "label" 

instead of custom function which returns always the same I dont know exactly in which field you are saving that artist name, is it label ? Cause I dont see "name" field in schema

proletesseract commented 8 years ago

Any idea how to get the correct _id for the row so I can pass it into the ArtistImages.findOne() call in that first code block?

I've tried to console.log(this) and searched through it for anything useful with no leads.

I'm not trying to save the name against artistImages at this point, I'm just trying to display it in the "view all" section so we can easily see which images are associated to which artist.

In the ArtistImages schema there's the autoform element which builds a dropdown with all the artists and their id's which gets saved into the artistId field of ArtistImages. That part is all working fine, the artistId is saving correctly to the artist image but I can't pull the artist name into the list view for some reason.

The artist schema looks like this:

Artists = new Mongo.Collection("artists");

var Schemas = {};

Schemas.Artist = new SimpleSchema({
    name: {
        type: String,
        label: "Name",
        max: 200,
        optional: true
    },
    description: {
        type: String,
        label: "Description",
        autoform: {
            rows: 5
        },
        optional: true
    },
    soundcloud: {
        type: String,
        label: "SoundCloud",
        max: 200,
        optional: true
    },
    country: {
        type: String,
        label: "Country",
        max: 200,
        optional: true
    }
});

Artists.attachSchema(Schemas.Artist);
proletesseract commented 8 years ago

It seems like the document is passed into the function in the meteor-admin configuration like this:

...
ArtistImages: {
    tableColumns: [
        { label: 'ArtistId', name: 'artistId' },
        { label: 'Artist', name: function(doc) {
                return ArtistImages.findOne({_id: doc._id}).artist();
            }
        },
        { label: 'Image', name: 'image' },
    ]
},
...

The rest of the code is correct, this fixes the issue. Pity its not documented, I just had a brainwave, tried it and it worked!

dbismut commented 8 years ago

This is critical I think. Not to mention that I found that using collection-helpers makes a document not serializable and therefore cannot be properly used by quickForm in editing mode: the form shows an empty document (at least in my case). I think even Session has a hard time storing a document with helpers (which makes Session.set('admin_doc', docWithHelpers) useless).

Thanks @craigmacgregor for providing an alternative to helpers.