F. Rick Reich
F. Rick Reich

Reputation: 89

mongoose return json list of tags specified as subdocuments

so i am having this problem that keeps me busy for the past 4 days, i am having a schema and subdocument schema like this:

var mongoose = require( 'mongoose' ),
    Schema = mongoose.Schema;

var ProjectSchema = new Schema({
    name: String,
    author: String,
    category: String,
    description: String,
    tags: [TagSchema]
});

var TagSchema = new Schema({
    name: String,
    date: Date
});

mongoose.model( 'TagSchema', TagSchema );
mongoose.model( 'Project', Project );

and what i want to have is a list of all tags of all ProjectSchemas, whatever i try i either get NONE or just the ones of the most current Project. i just dont know further because whatever i do i always end up failing on this one. what am i doing wrong, is there no such thing as a findAll for mongoose?

app.get('/tags.json', function(req, res) {
    TagSchema.find({}, function ( err, tags ){
        var json = JSON.stringify(tags);
        console.log(json);
    tags = tags.map(function (tag) {
        return tag.toObject();
    });
    console.log(json == JSON.stringify(tags));
    res.json(json);
    });
});

and

app.get('/tags.json', function(req, res) {
    Project.find(function (err, projects) {
        projects.forEach( function( project ){
            res.json(project.tags);
        });
    });
});

and anything else i tried just returned

[ ]

or errored out...

(additionally i wonder, how can i make sure that if i add a tag to a project and its already existant how i can keep it from adding.)

Upvotes: 3

Views: 1664

Answers (3)

F. Rick Reich
F. Rick Reich

Reputation: 89

with the help of @alawson421's code and some array magic it works perfectly, thanks again @JohnnyHK for showing me the difference between a schema and a model. heres the working fix:

app.get('/tags.json', function(req, res) {
    ProjectModel.find(function (err, projects) {
        var taglist = [];

        projects.forEach( function( project ){
            //console.log(JSON.stringify(project.tags));
            project.tags.forEach( function( tag ){
                console.log(tag);
                taglist.push(tag.name);
            }); 
        });

        res.json(taglist);
    });
});

and the output is:

[
    "test",
    "meep",
    "lalela",
    "another test",
    "ihopethisworks",
    "noderocks",
    "i am not a mongo",
    "ice cream rocks"
]

Upvotes: 1

anthonylawson
anthonylawson

Reputation: 781

You are trying to call find on the schema, when you should be trying to call it on a model.

If you change the bottom of your file to:

var TagModel     = mongoose.model( 'TagModel', TagSchema );
var ProjectModel = mongoose.model( 'ProjectModel', Project );

and then in your app.get function calls:

app.get('/tags.json', function(req, res) {
    TagModel.find({}, function ( err, tags ){ //changed this to the model instead of the schema
        var json = JSON.stringify(tags);
        console.log(json);
    tags = tags.map(function (tag) {
        return tag.toObject();
    });
    console.log(json == JSON.stringify(tags));
    res.json(json);
    });
});

and

app.get('/tags.json', function(req, res) {
    ProjectModel.find(function (err, projects) {
        projects.forEach( function( project ){
            res.json(project.tags);
        });
    });
});

Models are constructors compiled from your schema definitions and represent the documents that can be saved and queried from the db.

Upvotes: 3

JohnnyHK
JohnnyHK

Reputation: 311925

When you use TagSchema in its own model and embedded in ProjectSchema like you are, it's important to understand that the docs in the tags collection and the docs in the tags array of project docs have no inherent connection. So if you save tags as part of a project, those won't end up in the tags collection unless you explicitly add them to that as well.

A few specific problems in your posted code:

  1. You need to define TagSchema before you use it in ProjectSchema.
  2. You should be passing ProjectSchema into the mongoose.model call, not Project.
  3. Keep your schema and model names separate as it's not clear what's what in your code.

Upvotes: 2

Related Questions