Skip to content

Commit 51128bd

Browse files
Add new hook 'loaded'
1 parent 019705d commit 51128bd

File tree

2 files changed

+604
-121
lines changed

2 files changed

+604
-121
lines changed

lib/dao.js

Lines changed: 188 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -285,21 +285,39 @@ DataAccessObject.create = function (data, options, cb) {
285285
}
286286
obj.__persisted = true;
287287

288-
saveDone.call(obj, function () {
289-
createDone.call(obj, function () {
290-
if (err) {
291-
return cb(err, obj);
292-
}
293-
var context = {
294-
Model: Model,
295-
instance: obj,
296-
isNewInstance: true,
297-
hookState: hookState,
298-
options: options
299-
};
300-
Model.notifyObserversOf('after save', context, function(err) {
301-
cb(err, obj);
302-
if(!err) Model.emit('changed', obj);
288+
var context = {
289+
Model: Model,
290+
data: val,
291+
isNewInstance: true,
292+
hookState: hookState,
293+
options: options
294+
};
295+
Model.notifyObserversOf('loaded', context, function(err) {
296+
297+
// Per current implementation, context of `create` does NOT
298+
// have the data updated through persist/loaded hooks.
299+
// So, introduced a new property `applyHookUpdates`, which
300+
// if set, returns the updated context.
301+
if(Model.settings.applyHookUpdates) {
302+
obj = new Model(context.data);
303+
}
304+
saveDone.call(obj, function () {
305+
createDone.call(obj, function () {
306+
if (err) {
307+
return cb(err, obj);
308+
}
309+
var context = {
310+
Model: Model,
311+
instance: obj,
312+
isNewInstance: true,
313+
hookState: hookState,
314+
options: options
315+
};
316+
317+
Model.notifyObserversOf('after save', context, function(err) {
318+
cb(err, obj);
319+
if(!err) Model.emit('changed', obj);
320+
});
303321
});
304322
});
305323
});
@@ -475,33 +493,42 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
475493
});
476494
}
477495
function done(err, data, info) {
478-
var obj;
479-
if (data && !(data instanceof Model)) {
480-
inst._initProperties(data, { persisted: true });
481-
obj = inst;
482-
} else {
483-
obj = data;
484-
}
485-
if (err) {
486-
cb(err, obj);
487-
if(!err) {
488-
Model.emit('changed', inst);
496+
var context = {
497+
Model: Model,
498+
data: data,
499+
hookState: ctx.hookState,
500+
options: options
501+
};
502+
Model.notifyObserversOf('loaded', context, function(err) {
503+
var obj;
504+
if (data && !(data instanceof Model)) {
505+
inst._initProperties(data, { persisted: true });
506+
obj = inst;
507+
} else {
508+
obj = data;
489509
}
490-
} else {
491-
var context = {
492-
Model: Model,
493-
instance: obj,
494-
isNewInstance: info ? info.isNewInstance : undefined,
495-
hookState: hookState,
496-
options: options
497-
};
498-
Model.notifyObserversOf('after save', context, function(err) {
510+
if (err) {
499511
cb(err, obj);
500512
if(!err) {
501513
Model.emit('changed', inst);
502514
}
503-
});
504-
}
515+
} else {
516+
var context = {
517+
Model: Model,
518+
instance: obj,
519+
isNewInstance: info ? info.isNewInstance : undefined,
520+
hookState: hookState,
521+
options: options
522+
};
523+
524+
Model.notifyObserversOf('after save', context, function(err) {
525+
cb(err, obj);
526+
if(!err) {
527+
Model.emit('changed', inst);
528+
}
529+
});
530+
}
531+
});
505532
}
506533
});
507534
} else {
@@ -586,36 +613,46 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
586613
function _findOrCreate(query, data, currentInstance) {
587614
var modelName = self.modelName;
588615
function findOrCreateCallback(err, data, created) {
589-
var obj, Model = self.lookupModel(data);
616+
var context = {
617+
Model: Model,
618+
data: data,
619+
isNewInstance: created,
620+
hookState: hookState,
621+
options: options
622+
};
623+
Model.notifyObserversOf('loaded', context, function(err) {
624+
var obj, Model = self.lookupModel(data);
590625

591-
if (data) {
592-
obj = new Model(data, {fields: query.fields, applySetters: false,
593-
persisted: true});
594-
}
626+
if (data) {
627+
obj = new Model(data, {fields: query.fields, applySetters: false,
628+
persisted: true});
629+
}
595630

596-
if (created) {
597-
var context = {
598-
Model: Model,
599-
instance: obj,
600-
isNewInstance: true,
601-
hookState: hookState,
602-
options: options
603-
};
604-
Model.notifyObserversOf('after save', context, function(err) {
631+
if (created) {
632+
var context = {
633+
Model: Model,
634+
instance: obj,
635+
isNewInstance: true,
636+
hookState: hookState,
637+
options: options
638+
};
639+
Model.notifyObserversOf('after save', context, function(err) {
640+
if (cb.promise) {
641+
cb(err, [obj, created]);
642+
} else {
643+
cb(err, obj, created);
644+
}
645+
if (!err) Model.emit('changed', obj);
646+
});
647+
648+
} else {
605649
if (cb.promise) {
606650
cb(err, [obj, created]);
607651
} else {
608652
cb(err, obj, created);
609653
}
610-
if (!err) Model.emit('changed', obj);
611-
});
612-
} else {
613-
if (cb.promise) {
614-
cb(err, [obj, created]);
615-
} else {
616-
cb(err, obj, created);
617654
}
618-
}
655+
});
619656
}
620657

621658
data = removeUndefined(data);
@@ -1329,38 +1366,50 @@ DataAccessObject.find = function find(query, options, cb) {
13291366
var Model = self.lookupModel(d);
13301367
var obj = new Model(d, {fields: query.fields, applySetters: false, persisted: true});
13311368

1332-
if (query && query.include) {
1333-
if (query.collect) {
1334-
// The collect property indicates that the query is to return the
1335-
// standalone items for a related model, not as child of the parent object
1336-
// For example, article.tags
1337-
obj = obj.__cachedRelations[query.collect];
1338-
if (obj === null) {
1339-
obj = undefined;
1340-
}
1341-
} else {
1342-
// This handles the case to return parent items including the related
1343-
// models. For example, Article.find({include: 'tags'}, ...);
1344-
// Try to normalize the include
1345-
var includes = Inclusion.normalizeInclude(query.include || []);
1346-
includes.forEach(function(inc) {
1347-
var relationName = inc;
1348-
if (utils.isPlainObject(inc)) {
1349-
relationName = Object.keys(inc)[0];
1350-
}
1369+
context = {
1370+
Model: Model,
1371+
instance: obj,
1372+
isNewInstance: false,
1373+
hookState: hookState,
1374+
options: options
1375+
};
13511376

1352-
// Promote the included model as a direct property
1353-
var included = obj.__cachedRelations[relationName];
1354-
if (Array.isArray(included)) {
1355-
included = new List(included, null, obj);
1377+
if (query && query.include) {
1378+
Model.notifyObserversOf('loaded', context, function(err) {
1379+
if (query.collect) {
1380+
// The collect property indicates that the query is to return the
1381+
// standalone items for a related model, not as child of the parent object
1382+
// For example, article.tags
1383+
obj = obj.__cachedRelations[query.collect];
1384+
if (obj === null) {
1385+
obj = undefined;
13561386
}
1357-
if (included) obj.__data[relationName] = included;
1358-
});
1359-
delete obj.__data.__cachedRelations;
1360-
}
1387+
} else {
1388+
// This handles the case to return parent items including the related
1389+
// models. For example, Article.find({include: 'tags'}, ...);
1390+
// Try to normalize the include
1391+
var includes = Inclusion.normalizeInclude(query.include || []);
1392+
includes.forEach(function(inc) {
1393+
var relationName = inc;
1394+
if (utils.isPlainObject(inc)) {
1395+
relationName = Object.keys(inc)[0];
1396+
}
1397+
1398+
// Promote the included model as a direct property
1399+
var included = obj.__cachedRelations[relationName];
1400+
if (Array.isArray(included)) {
1401+
included = new List(included, null, obj);
1402+
}
1403+
if (included) obj.__data[relationName] = included;
1404+
});
1405+
delete obj.__data.__cachedRelations;
1406+
}
1407+
});
13611408
}
13621409
if (obj !== undefined) {
1363-
results.push(obj);
1410+
Model.notifyObserversOf('loaded', context, function(err) {
1411+
results.push(obj);
1412+
});
13641413
}
13651414
}
13661415

@@ -1803,22 +1852,33 @@ DataAccessObject.prototype.save = function (options, cb) {
18031852
if (err) {
18041853
return cb(err, inst);
18051854
}
1806-
inst._initProperties(data, { persisted: true });
1855+
18071856
var context = {
18081857
Model: Model,
1809-
instance: inst,
1858+
data: data,
18101859
isNewInstance: result && result.isNewInstance,
18111860
hookState: hookState,
18121861
options: options
18131862
};
1814-
Model.notifyObserversOf('after save', context, function(err) {
1815-
if (err) return cb(err, inst);
1816-
updateDone.call(inst, function () {
1817-
saveDone.call(inst, function () {
1818-
cb(err, inst);
1819-
if(!err) {
1820-
Model.emit('changed', inst);
1821-
}
1863+
Model.notifyObserversOf('loaded', context, function(err) {
1864+
inst._initProperties(data, { persisted: true });
1865+
1866+
var context = {
1867+
Model: Model,
1868+
instance: inst,
1869+
isNewInstance: result && result.isNewInstance,
1870+
hookState: hookState,
1871+
options: options
1872+
};
1873+
Model.notifyObserversOf('after save', context, function(err) {
1874+
if (err) return cb(err, inst);
1875+
updateDone.call(inst, function () {
1876+
saveDone.call(inst, function () {
1877+
cb(err, inst);
1878+
if(!err) {
1879+
Model.emit('changed', inst);
1880+
}
1881+
});
18221882
});
18231883
});
18241884
});
@@ -1956,7 +2016,15 @@ DataAccessObject.updateAll = function (where, data, options, cb) {
19562016

19572017
function updateCallback(err, info) {
19582018
if (err) return cb (err);
2019+
19592020
var context = {
2021+
Model: Model,
2022+
data: data,
2023+
hookState: hookState,
2024+
options: options
2025+
};
2026+
2027+
context = {
19602028
Model: Model,
19612029
where: where,
19622030
data: data,
@@ -2290,20 +2358,29 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
22902358
}
22912359

22922360
function updateAttributesCallback(err) {
2293-
if (!err) inst.__persisted = true;
2294-
done.call(inst, function () {
2295-
saveDone.call(inst, function () {
2296-
if (err) return cb(err, inst);
2297-
var context = {
2298-
Model: Model,
2299-
instance: inst,
2300-
isNewInstance: false,
2301-
hookState: hookState,
2302-
options: options
2303-
};
2304-
Model.notifyObserversOf('after save', context, function(err) {
2305-
if(!err) Model.emit('changed', inst);
2306-
cb(err, inst);
2361+
var context = {
2362+
Model: Model,
2363+
data: data,
2364+
hookState: hookState,
2365+
options: options
2366+
};
2367+
Model.notifyObserversOf('loaded', context, function(err) {
2368+
if (!err) inst.__persisted = true;
2369+
done.call(inst, function () {
2370+
saveDone.call(inst, function () {
2371+
if (err) return cb(err, inst);
2372+
2373+
var context = {
2374+
Model: Model,
2375+
instance: inst,
2376+
isNewInstance: false,
2377+
hookState: hookState,
2378+
options: options
2379+
};
2380+
Model.notifyObserversOf('after save', context, function(err) {
2381+
if(!err) Model.emit('changed', inst);
2382+
cb(err, inst);
2383+
});
23072384
});
23082385
});
23092386
});

0 commit comments

Comments
 (0)