I have this code extension of insert method in problems.collection.ts. I need find last inserted object, get lastId and increase it.
Every object has own unique ID, but I want create in every object "problemSecondId" that will be more suitable and will be presented to user in my app.
So when I create first "Problem" in collection, I get console.log "undefined" in variable "lastProblem" and object is created with "problemSecondId: 1". When I create second "Problem", I get again "undefined" and second "Problem" is created with "problemSecondId: 1" too!!! I tried a lot of things.
Code behaves, that the query "findOne" returns "undefined" so I think, that mistake is in query, or possible mistake can be that collection "Problems" is not Mongo.Collection but MongoObservable.Collection... ? Can somebody help me? thnx.
import { MongoObservable } from "meteor-rxjs";
import { Problem } from "../models/problem.model";
import { Observable } from "rxjs";
import { Mongo } from "meteor/mongo";
class ProblemCollection extends Mongo.Collection {
insert(problem, callback) {
if (!problem.problemSecondId) {
let lastProblem = Problems.findOne({}, { sort: { problemSecondId: -1 }});
console.log(lastProblem);
if (lastProblem){
let lastProblemId = lastProblem.problemSecondId++;
problem.problemSecondId = lastProblemId;
} else {
problem.problemSecondId = 1;
}
}
return super.insert(problem, callback);
}
}
let problems = new ProblemCollection("problems");
export const Problems = new MongoObservable.Collection<Problem>(problems);
function loggedIn() {
return !!Meteor.user();
}
Problems.allow({
insert: loggedIn,
update: loggedIn,
remove: loggedIn
});
This seems to be a good example for misuse of the postfix increment (++
) operator.
let x = 5;
let y = x++; // x = 6, y = 5
The expression involving the postfix operator evaluates to the value before the increment.
Thing is, there was no real need for it in the first place. You have no need to increment lastProblem
's problemSecondId
property, since all you wanted to do is set that same property of the problem
object.
Simply using:
problem.problemSecondId = lastProblem.problemSecondId + 1;
would be clearer, in my opinion, and has the advantage of actually doing what you intend.
The fact that your query returns undefined
on the client does not necessarily imply that this is the case on the server as well, since the data available on the client may not reflect the database contents.
As a side note, take into account that you may run into a race condition, where 2 problem
s are created at close proximity, and both can get the same problemSecondId
, since the combination of actions (find
and update
) is not atomic and there are no locks in use.
I added to the code "Meteor.isServer" condition to execute code only on server. Result is that I have NO output in console and terminal (and in MongoDb is created object and "problemSecondId" completely missing). So I am very unhappy with solving this problem. Couldn´t be problem with, that problems.collection.ts is situated in meteort/both/collections/... I think, that is right, because collection is used both (client and server). Edited code below:
import { MongoObservable } from "meteor-rxjs";
import { Problem } from "../models/problem.model";
import { Observable } from "rxjs";
import { Mongo } from "meteor/mongo";
class ProblemCollection extends Mongo.Collection {
insert(problem, callback) {
if (Meteor.isServer) {
if (!problem.problemSecondId) {
let lastProblem = Problems.findOne({}, { sort: { problemSecondId: -1 } });
console.log(lastProblem);
if (lastProblem) {
console.log('xxx');
let lastProblemId = lastProblem.problemSecondId + 1;
problem.problemSecondId = lastProblemId;
} else {
console.log('yyy')
problem.problemSecondId = 1;
}
}
}
return super.insert(problem, callback);
}
}
let problems = new ProblemCollection("problems");
export const Problems = new MongoObservable.Collection<Problem>(problems);
Problems.allow({
insert: loggedIn,
update: loggedIn,
remove: loggedIn
});
function loggedIn() {
return !!Meteor.user();
}