@@ -408,25 +408,23 @@ function fromDb(json: any, options?: IFromDbOptions): object {
408408 const propertyNames = Object . getOwnPropertyNames ( source ) ;
409409 for ( const key of propertyNames ) {
410410
411- if ( shouldRecurse ( source [ key ] ) ) {
412-
413- // convert the DB key name to the Model key name
414- const mapper = map ( key , source [ key ] , dbOptionsByFieldName ) ;
411+ // convert the DB key name to the Model key name
412+ const mapper = map ( key , source [ key ] , dbOptionsByFieldName ) ;
413+ const model = mapper . model ;
414+
415+ let nextTarget ;
416+ try {
417+ nextTarget = ( model )
418+ ? Object . assign ( new model ( ) , target [ mapper . newKey ] )
419+ : target [ mapper . newKey ] ;
420+ } catch ( err ) {
421+ throw new Error ( `Model '${ modelName } ' has a property '${ key } ' that defines its model with a value that`
422+ + ` cannot be constructed` ) ;
423+ }
415424
425+ if ( shouldRecurse ( source [ key ] ) ) {
416426 // if the key should be included, recurse into it
417427 if ( mapper . newKey !== undefined ) {
418- const model = mapper . model ;
419-
420- // if recurrsing into a model, set that up, otherwise just pass the target in
421- let nextTarget ;
422- try {
423- nextTarget = ( model )
424- ? Object . assign ( new model ( ) , target [ mapper . newKey ] )
425- : target [ mapper . newKey ] ;
426- } catch ( err ) {
427- throw new Error ( `Model '${ modelName } ' has a property '${ key } ' that defines its model with a value that`
428- + ` cannot be constructed` ) ;
429- }
430428
431429 let value = mapDbToModel ( source [ key ] , nextTarget , map , ++ depth ) ;
432430
@@ -441,13 +439,13 @@ function fromDb(json: any, options?: IFromDbOptions): object {
441439 target [ mapper . newKey ] = value ;
442440 }
443441
444- continue ;
445- }
446-
447- // otherwise, map a property that has a primitive value or an ObjectID value
448- const mapper = map ( key , source [ key ] , dbOptionsByFieldName ) ;
449- if ( mapper . newKey !== undefined ) {
450- target [ mapper . newKey ] = source [ key ] ;
442+ } else {
443+ // otherwise, map a property that has a primitive value or an ObjectID value
444+ if ( mapper . newKey !== undefined ) {
445+ target [ mapper . newKey ] = ( source [ key ] !== undefined && source [ key ] !== null )
446+ ? source [ key ]
447+ : nextTarget ; // resolves issue #94
448+ }
451449 }
452450 }
453451
@@ -470,12 +468,13 @@ function fromDb(json: any, options?: IFromDbOptions): object {
470468 function pruneNonDbProperties ( source , target ) {
471469 const dbOptionsByProperty : Map < string , IDbOptions > = Reflect . getMetadata ( dbSymbols . dbByPropertyName , target ) ;
472470
473- for ( const key of Object . getOwnPropertyNames ( target ) ) {
471+ const keys = Object . getOwnPropertyNames ( target ) ;
472+ for ( const key of keys ) {
474473
475474 const dbOptions = ( dbOptionsByProperty ) ? dbOptionsByProperty . get ( key ) || { } : null ;
476475 const fieldName = ( dbOptions ) ? dbOptions . field || key : key ;
477476
478- if ( ! source . hasOwnProperty ( fieldName ) ) {
477+ if ( ! ! source && ! source . hasOwnProperty ( fieldName ) ) {
479478 if ( key === 'id' && source . hasOwnProperty ( '_id' ) ) {
480479 continue ;
481480 }
@@ -836,6 +835,14 @@ function getCursorById(id, project?: any): Cursor<any> {
836835function getDb ( ) : Db {
837836 // can be called as instance or static method, so get the appropriate context
838837 const constructor = this [ modelSymbols . constructor ] || this ;
838+
839+ if ( ! constructor . sapi ) {
840+ const target = constructor . name || constructor . constructor . name ;
841+ throw new Error ( `getDb called on model ${ target } without an instance of ` +
842+ `SakuraAPI. Make sure you pass ${ target } into the Model injector when you're ` +
843+ `instantiating SakuraApi` ) ;
844+ }
845+
839846 const db = constructor [ modelSymbols . sapi ] . dbConnections . getDb ( constructor [ modelSymbols . dbName ] ) ;
840847
841848 debug . normal ( `.getDb called, dbName: '${ constructor [ modelSymbols . dbName ] } ', found?: ${ ! ! db } ` ) ;
0 commit comments