2016-06-25 4 views
0

Adam Bretz &の "MEANを使った完全なスタックJavaScript開発"の第8章の例を使って作業してください。本書のコードはdoesnではありません(おそらく意図的に)完全ではないようだ。 IveはグーグルやStackOverflowのデバッグに多くの時間を費やしました。このスクリプトは、insertEmployeeが実行されてからbailsまで実行されます。私は、insertEmployee引数(pd、devops、acct)の引数がどのように設定されるかを理解できません。私は "コールバック地獄"に立ち往生!TypeError:未定義の '_id'プロパティを読み取ることができない

基本的に私はであり、ノードを使用してMongoDbを埋め込むです。

If I set the insertEmployee function to use pd._id for all the employees its fine, but using devops._id or acct._id always results in the error below

*TypeError: Cannot read property '_id' of undefined 
    at insertEmployees (/Users/Bluemagma/Sites/NodeJS Example Application/database/humanresourcesSchema.js:111:17) 
    at /Users/Bluemagma/Sites/NodeJS Example Application/database/humanresourcesSchema.js:199:3 
    at /Users/Bluemagma/Sites/NodeJS Example Application/database/humanresourcesSchema.js:62:4 
    at Function.<anonymous> (/Users/Bluemagma/Sites/NodeJS Example Application/node_modules/mongoose/lib/model.js:3352:16) 
    at /Users/Bluemagma/Sites/NodeJS Example Application/node_modules/mongoose/lib/model.js:1863:18 
    at /Users/Bluemagma/Sites/NodeJS Example Application/node_modules/async/lib/async.js:726:13 
    at /Users/Bluemagma/Sites/NodeJS Example Application/node_modules/async/lib/async.js:52:16 
    at done (/Users/Bluemagma/Sites/NodeJS Example Application/node_modules/async/lib/async.js:246:17) 
    at /Users/Bluemagma/Sites/NodeJS Example Application/node_modules/async/lib/async.js:44:16 
    at /Users/Bluemagma/Sites/NodeJS Example Application/node_modules/async/lib/async.js:723:17 
    at /Users/Bluemagma/Sites/NodeJS Example Application/node_modules/async/lib/async.js:167:37 
    at model.callbackWrapper (/Users/Bluemagma/Sites/NodeJS Example Application/node_modules/mongoose/lib/model.js:1841:11) 
    at next_ (/Users/Bluemagma/Sites/NodeJS Example Application/node_modules/hooks-fixed/hooks.js:89:34) 
    at fnWrapper (/Users/Bluemagma/Sites/NodeJS Example Application/node_modules/hooks-fixed/hooks.js:186:18) 
    at /Users/Bluemagma/Sites/NodeJS Example Application/node_modules/mongoose/lib/model.js:3352:16 
    at /Users/Bluemagma/Sites/NodeJS Example Application/node_modules/mongoose/lib/model.js:228:5* 

humanresourcesSchema.js

var mongoose = require('mongoose'); 
var Schema = mongoose.Schema; 
var db = mongoose.connection; 
var dbUrl = 'mongodb://localhost/humanResources'; 

var TeamSchema = new Schema({ 
    name: { 
     type: String, 
     required: true 
    } 
}); 

var Team = mongoose.model('Team', TeamSchema); 

var EmployeeSchema = new Schema({ 
    name: { 
     first: { 
      type: String, 
      required: true 
     }, 
     last: { 
      type: String, 
      required: true 
     } 
    }, 
    team: { 
     type: Schema.Types.ObjectId, 
     ref: 'Team' 
    }, 
    image: { 
     type: String, 
     default: 'images/user.png' 
    }, 
    address: { 
     lines: { 
      type: [String] 
     }, 
     postal: { 
      type: String 
     } 
    } 
}); 

var Employee = mongoose.model('Employee', EmployeeSchema); 

db.on('error', function() { 
    console.log('there was an error communicating with the damn database'); 
}); 

function insertTeams (callback) { 
    Team.create([{ 
     name: 'Product Development' 
    }, { 
     name: 'Dev Ops' 
    }, { 
     name: 'Accounting' 
    }], function (error, pd, devops, acct) { 
     if (error) { 
      return callback(error); 
     } else { 
      console.info('teams sucessfully added sir!'); 
      callback(null, pd, devops, acct);   
     } 
    }); 
} 

function retrieveEmployee (data, callback) { 
    Employee.findOne({ 
     _id: data.employee._id 
    }).populate('team').exec(function (error, result) { 
     if (error) { 
      return callback (error); 
     } else { 
      console.log('*** Single Employee Result ***'); 
      console.dir(result); 
      callback(null, data); 
     } 
    }); 
} 

function retrieveEmployees (data, callback) { 
    Employee.find({ 
     'name.first': /J/i 
    }, function (error, results) { 
     if (error) { 
      return callback(error); 
     } else { 
      console.log('*** Multiple Employees Result ***'); 
      console.dir(results); 
      callback(null, data); 
     } 
    }); 
} 

function insertEmployees (pd, devops, acct, callback) { 
    Employee.create([{ 
    name: { 
     first: 'John', 
     last: 'Adams' 
    }, 
    Team: pd._id, 
    address: { 
     lines: ['2 Lincoln Memorial Cir NW'], 
     postal: '20037' 
    } 
    }, { 
    name: { 
     first: 'Thomas', 
     last: 'Jefferson' 
    }, 
    Team: devops._id, 
    address: { 
     lines: ['1600 Pennsylvania Avenue', 'White House'], 
     postal: '20500' 
    } 
    }, { 
    name: { 
     first: 'James', 
     last: 'Madison' 
    }, 
    team: acct._id, 
    address: { 
     lines: ['2 15th St NW', 'PO Box 8675309'], 
     postal: '20007' 
    } 
    }, { 
    name: { 
     first: 'James', 
     last: 'Monroe' 
    }, 
    team: acct._id, 
    address: { 
     lines: ['1850 West Basin Dr SW', 'Suite 210'], 
     postal: '20242' 
    } 
    }], function (error, johnadams) { 
    if (error) { 
     return callback(error); 
    } else { 
     console.info('employees successfully added sir!'); 
     callback(null, { 
     team: pd, 
     employee: johnadams 
     }); 
    } 
    }) 
} 

function updateEmployee (first, last, data, callback) { 
    console.log('*** Changin names ***'); 
    console.dir(data.employee); 

    var employee = data.employee; 
    employee.name.first = first; 
    employee.name.last = last; 

    employee.save(function (error, result) { 
     if (error) { 
      return callback (error); 
     } else { 
      console.log('*** Changed name to Andrew Jackson ***'); 
      console.log(result); 
      callback(null, data); 
     } 
    }); 
} 

function removeTeams() { 
    console.info("deleting all previously added teams sir!"); 
    Team.remove({}, function(error, response) { 
     if(error) { 
      console.error("tried to delete all teams but " + error); 
     } 
     console.info("done deleting all teams sir!"); 
    }); 
} 

function removeEmployees() { 
    console.info("deleting all previously added employees sir!"); 
    Employee.remove({}, function(error, response) { 
     if(error) { 
      console.error("tried to delete all employees but " + error); 
     } 
     console.info("done deleting all employees sir!"); 
    }); 
} 

mongoose.connect(dbUrl, function (err) { 
    if (err) { 
     return console.log('there was a problem connecting to the database sir!' + err); 
    } 
    console.log('connected to the database sir!'); 
    removeTeams(); 
    removeEmployees(); 
    insertTeams(function (error, pd, devops, acct) { 
     if (error) { 
      return console.log(error); 
     } 
     insertEmployees(pd, devops, acct, function (err, result){ 

      retrieveEmployee(result, function(err, result) { 

       retrieveEmployees(result, function(err, result) { 

        updateEmployee('Andrew', 'Jackson', result, function(err, result) { 
         if (err) { 
         console.error(err); 
        } else { 
         console.info("database activity complete sir!"); 
        } 

        db.close(); 
        process.exit(); 
        }); 
       }); 
      }); 
     }); 
    }); 
}); 

ためHERESに私のコードは、あなたの助けのノードとMongoの天才をありがとう!私は、コールバックの詳細を学ぶのを楽しみにしています

+0

私は最初にpd以外の引数を使っているImは "Team:devops._id"という行111を追加するべきです。 Team:pd._idにすべて設定しても問題はありません。 – bluemagma

答えて

1
function insertTeams (callback) { 
    Team.create([{ 
     name: 'Product Development' 
    }, { 
     name: 'Dev Ops' 
    }, { 
     name: 'Accounting' 
    }], function (error, pd, devops, acct) { 
     if (error) { 
      return callback(error); 
     } else { 
      console.info('teams sucessfully added sir!'); 
      callback(null, pd, devops, acct);   
     } 
    }); 
} 

こちらのコールバックは私には疑わしいです。 Team.create()に1つの引数として配列を渡すので、結果は挿入されたドキュメントを含む配列であるfunction(err, results)としてコールバックされます。

コールバックをcallback(null, pd, devops, acct);のように呼び出すと、エラーはnullになり、pdは結果配列になり、devopsとacctは未定義になります。

Team.createの個別の引数としてチームを渡すことも、複数の引数を指定してコールバックを呼び出すことも、そのままにして配列を処理するコールバックを調整することもできます。

function insertTeams (callback) { 
    Team.create({ 
     name: 'Product Development' 
    }, { 
     name: 'Dev Ops' 
    }, { 
     name: 'Accounting' 
    }, function (error, pd, devops, acct) { 
     if (error) { 
      return callback(error); 
     } else { 
      console.info('teams sucessfully added sir!'); 
      callback(null, pd, devops, acct);   
     } 
    }); 
} 

いくつかのよく配置コンソール:ここ

Mongoose examples.

かは(たぶん)「ラッキング私の日のために持っていたと私はちょうど2つのブラケットを削除する必要がありました」バージョンです。log()は、変数をどこから外しているかを知ることで多くの助けになります。

+0

ありがとうございました!私は間違いなくこれを試し、mongoose文書へのリンクを投稿してくれてありがとう! – bluemagma

+0

あなたが提案したように括弧を外しました。私はまだ動作していますが、デバッグを助けてくれてありがとう! – bluemagma

+0

私がリンクしているドキュメントには、「灰色のボックスに表示されている例がありますが、「個々のドキュメントを渡す」と「配列を渡す」の違いが示されています。私はあなたがそれとの違いを理解できると思います。また、私は答えを受け入れるstackoverflowのプロセスを指摘するかもしれない:) http://stackoverflow.com/help/accepted-answer – marton

0

私はあなたがinsertTeams関数でエラーが発生していると感じています。

エラーでコールバック関数(insertEmployees)を呼び出すと、関数はエラーが発生した場合にエラーをキャッチまたは処理しません。代わりに、コールバックを呼び出し、エラー自体を引数として渡します。 insertEmployeesにはエラー処理がないため、エラーが発生したかどうかをチェックしません。したがって、devopsの_idプロパティーを呼び出そうとすると、関数が呼び出されたときに定義されていないので、devopsは未定義です。したがって、JSエラーアウト。

詳細については、insertTeamsでエラーが発生した場合にログに記録してみてください。

編集:コールバック(エラー)でinsertEmployeesが呼び出されているという問題がまだ発生していると思います。エラーの_idフィールドにアクセスすることができます。エラーが存在するため、少なくともundefinedが返されます。しかし、他の引数は関数に渡されないので定義されていないので、未定義オブジェクトのフィールドにアクセスしようとしているので、それらの_idフィールドにアクセスしようとするとエラーが発生します。

+0

それは、私を助けてくれてありがとう、感謝します! – bluemagma

関連する問題