Running the code below I get an unexpected identifier error when checking if the documents state has changed. I've Googled this to death. tried to find documentation at Mongodb, here, and other misc sources without any luck. Ive spent the whole day on this and feel pretty stupid by now.
All help is sincerely appreciated.
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/course', function(err, db) {
if (err) throw err;
var weather = db.collection('weather');
var filter = {};
var projection ={'State':1, 'Temperature':1, _id:true};
var options = { 'skip' : 0,
'limit' : 20000 ,
'sort' : [['State', 1], ['Temperature', -1]] };
var cursor = weather.find(filter, projection, options);
var month_high = false;
var prevState = '';
var curID = '';
var operation = {'_id':curID,'$set':{'month_high':true}};
// get first document
cursor.first();
// initialize vars
prevState = doc.State;
// cycle through documents
cursor.each(function(err, doc) {
if(err) throw err;
if(doc == null) {
return db.close();
}
//Save current document Id
curID = doc._id;
// Check if State has changgd
if prevState != doc.state{
//If State has changed update the document
weather.update(operation,function(err,doc));
console.dir(doc); //we expect four documents to ouput.
}
// save current doc.state as previous state
prevState = doc.State;
;})
});
});
I think an unexpected identifier would be difficult to find on google. You may have extra closing braces or closing parentheses.
I don't see a closing parentheses for this opening parentheses:
MongoClient.connect(
Change the if prevState != doc.state{ to if (prevState != doc.state) { -- that is: add a pair of ( ).
To easily find such problems, you should use a Javascript syntax checker. Google this term and you'll get some good hits.
Also note that you have at least one other syntax problem in your code in
weather.update(operation,function(err,doc)); you use the function keyword but does not provide a function body. To make it pass syntax checks you should at least do: weather.update(operation,function(err,doc) {});
but you may want to add some logic inside the curly braces {}.
This was detected by http://esprima.org/demo/validate.html
One more thing, unrelated to the original question:
you use throw in your code for reporting errors. As the node/mongo predominantly use async APIs throwing an exception is almost meaningless. Take a look at questions such as:
Node.js Best Practice Exception Handling
Nested callbacks and exceptions handling in NodeJS
Catching exceptions from callbacks
Related
So I followed a udemy course on JS and during the making of an app he writes the code that is written bellow. When I come to run the code an error is raised saying "TypeError: this.validate is not a function". I tried different ways of exporting User and sometimes it told me that it cannot read User as a constructor which is what I want it to be. I have been on this for the past 4 hours and I am still unable to figure out how it works. The whole file is required by other files. When on these other files I create an instance of the object like below. It works although the .push method of an array cannot be accessed(error message pops up)when I call the pushError function
const User = require('../models/User.js')
let user = new User(req.body);
//I can then run the .validate function
user.validate();
//But in that function another error raises that says that the
//"push cannot be accessed in undefined"
//And it leads me to think that during the construction the
//empty list becomes undefined????
let User = function(data) {{
this.username = data.username;
this.mail = data.email;
this.password = data.password;
this.errors = [];
}
}
User.prototype.validate = function(){
if(this.username.replace(" ","") == ""){pushError("Username")}
if(this.password == ""){pushError("Password")}
if(this.mail.replace(" ","") == ""){pushError("Email")}
}
User.prototype.register = ()=>{
//Step #1: Validate user Data
this.validate();
//Step #2:If validated store data to DB
}
function pushError(str){
this.errors.push(`You must provide a valid ${str}.`);
};
module.exports = User;
If you read through all this thank you!
The problem is that your pushError function is in no way related to the User instance you are creating.
Inside pushError, this is not the new User object you're attempting to create, hence this.errors is undefined, and you cannot call push on undefined.
Also, writing register as an arrow function instead of a regular function makes it lose the value of this (this becomes that of the enclosing context, window in a browser or global in Node.js).
There three steps involved to solve this.
First you should rewrite pushError as part of User's prototype chain, like so:
User.prototype.pushError = function(str) {
this.errors.push(`You must provide a valid ${str}.`);
};
Second, you should use this.pushError instead of pushError in validate:
User.prototype.validate = function() {
if (this.username.replace(" ", "") == "") {
this.pushError("Username");
}
if (this.password == "") {
this.pushError("Password");
}
if (this.mail.replace(" ","") == "") {
this.pushError("Email");
}
}
Third, write register as a regular function:
User.prototype.register = function() {
//Step #1: Validate user Data
this.validate();
//Step #2:If validated store data to DB
}
That should do it. Now, a few additional comments and resources. It might help you to:
Dig into JavaScript Objects on MDN, especially the Object prototypes section.
Write your code as an ES6 class, which is a more "modern" way to do the same thing: this article gives examples of how to write things the "prototype way" or with classes.
Learn more about the differences between regular and "fat arrow" functions in this article.
I have some (pseudo) code that looks as follows
const { search, hash } = window.location // get search / hash from url
const tokenParts = queryParams(search || hash) // create an object
const { id_token, access_token } = tokenParts // extract from object
const isSessionValid = validateSession(id_token) // check exp time etc and return true / false
if (isSessionValid) {
store('id_token', id_token)
store('access_token', access_token)
window.history.replaceState(null, null, window.location.pathname)
}
I see this pattern a lot in the codebase I am working on, call a method with a value, assign that value to a variable, pass that variable into another method and assign the result to another variable....and so on until you have required value you require to move the program execution on.
From what I have read, functions should really, do-one-thing - rather than these massive, complex beats that can be difficult to test.
My question is, in the case of the pseudo code above, how can this be refactored into a function that returns the result of another function and so on?
I think I need something like
const sessionisValid = validateSession(window.location)
validateSession = ({search, hash}) => (queryParams(search || hash))=> hasTokenExp({id_token})
But I do not understand...
If this is how function programming / composition should work
Is the best approach
If I am just over complicating things
call a method with a value, assign that value to a variable, pass that variable into another method and assign the result to another variable... and so on until you have required value you require to move the program execution on.
This is totally fine. You're building on big function from multiple small functions - exactly how you should do it in functional programming. The variables are just necessary for the wiring.
What you have shown is not a massive, complex beast, it's very clear and clean code. It's easy to test all the individual small functions on their own if you want.
And because all those functions are pure and your variables are immutable, it's really easy to refactor your code from
const { search, hash } = window.location // get search / hash from url
const { id_token, access_token } = queryParams(search || hash)
const isSessionValid = validateSession(id_token) // check exp time etc
if (isSessionValid) {
store('id_token', id_token)
store('access_token', access_token)
window.history.replaceState(null, null, window.location.pathname)
}
to
function getSession({search, hash}) {
const { id_token, access_token } = queryParams(search || hash)
return {
id_token,
access_token,
isSessionValid: validateSession(id_token)
};
}
const { id_token, access_token, isSessionValid } = getSession(window.location);
if (isSessionValid) {
store('id_token', id_token)
store('access_token', access_token)
window.history.replaceState(null, null, window.location.pathname)
}
but unless you can use getSession in multiple places or you need this layer of abstraction for code organisation, the refactoring is unnecessary.
how can this be refactored to use function composition?
It can't really. Function composition works only when the result of one function are fed into another function and nowhere else. But in your code, access_token and id_token are used in multiple places. While it is possible to express this in pointfree style, it's complicated, slow and too abstract. Variables are much easier to use here.
I see this pattern a lot in the codebase I am working on
What exactly is the pattern? Whenever you see duplicated code, you might want to abstract out the common parts. But you need to be evaluate how many common parts and how many distinct parts there are in the code blocks. While always possible, often it's not worth it.
I have a piece of code show below that creates a Mongo collection as show below. However whenever I try to access the collection from inside of the Meteor.isClient scope I get an error. Please can anyone spot my mistake.
ImagesCollection = new Mongo.Collection("Images");
Images = new Mongo.Collection("Images");
if(Meteor.isClient){
Template.body.helpers({ images :
function() {
console.log("Template Loade");
return Images.find({},{sort: -1 });
}
}) ;
Template.Images.events({
'click .js-image' : function(event){
$(event.target).css("Width", "50px");
} ,
'click .js-del-image' : function(event){
var image_id = this._id ;
$("#"+image_id).hide({slow });
Images.remove({"_id" : image_id});
},
'click .js-rate-image' : function(event){
var rating = $(event.currentTarget).data("userrating");
var image_id = this.id ;
Images.find({"_id": image_id});
}
});
}
The content of my Startup.js is as below as well
if(Meteor.isServer){
Meteor.startup(function(){
for(var i = 0 ; i<=23 ; i++)
{
Images.insert({
'img_src' : 'img_'+i+'.jpg' ,
'img_alt' : 'Image number' + i
});
console.log(Images.find().count);
}
});
}
consle.log("Template Loade");
Since you don't specify your error, the line above will raise an error.
From the code that you have provided, there are two problems that I can see.
First, in your images template helper, your second parameter for the Images.find() function call is incorrect. You are missing a document field specification for the sort operation. This second parameter needs to be in the format {sort: {'document_field': -1}}. Although you have not provided the error text that you are seeing, I suspect the error has something to do with Mongo not being able to process the query, and this would be the reason for that.
Second, although this is less severe and should not be causing the problems with your inability to access the Images collection on the client, in your console.log() statement in your server Meteor.startup() code you are accessing count as if it is a property on the cursor returned from the Images.find() function call. In actuality, it is a function and should be called like so: Images.find().count().
Also, as an aside, I would suggest that you give different names to your two collections that you have defined. Giving them both the same name may cause issues for you if you are trying to manipulate data through the Mongo shell.
I am not sure if this is an issue, but why are you initializing twice the "images" collection ?
ImagesCollection = new Mongo.Collection("Images");
Images = new Mongo.Collection("Images");
And ImagesCollection is not used anywhere in you're code.
Try to remove one of this lines.
I am trying to add an object to a PFRelation in Cloud Code. I'm not too comfortable with JS but after a few hours, I've thrown in the towel.
var relation = user.relation("habits");
relation.add(newHabit);
user.save().then(function(success) {
response.success("success!");
});
I made sure that user and habit are valid objects so that isn't the issue. Also, since I am editing a PFUser, I am using the masterkey:
Parse.Cloud.useMasterKey();
Don't throw in the towel yet. The likely cause is hinted at by the variable name newHabit. If it's really new, that's the problem. Objects being saved to relations have to have once been saved themselves. They cannot be new.
So...
var user = // got the user somehow
var newHabit = // create the new habit
// save it, and use promises to keep the code organized
newHabit.save().then(function() {
// newHabit is no longer new, so maybe that wasn't a great variable name
var relation = user.relation("habits");
relation.add(newHabit);
return user.save();
}).then(function(success) {
response.success(success);
}, function(error) {
// you would have had a good hint if this line was here
response.error(error);
});
I have written code that parses a dictionary returned from Firebase containing images encoded using base64. I want it to simply write these images to file, and it does, but I receive the following error after my writes finish:
smalloc.cc:280: void node::smalloc::SliceOnto(const v8::FunctionCallbackInfo<v8::Value>&): Assertion `end <= source_len' failed.
This is my code:
// Iterate through each key in each page if each request
for (var key in request) {
var obj = request[key];
if (typeof (obj) == "object") {
for (var prop in obj) {
item++;
if(obj.hasOwnProperty(prop)) {
switch (prop) {
case "img":
var media = new ReceivedMedia(obj[prop]);
var filename = transaction.tid + "-" + item + "." + media.extension;
filename = filename.slice(10);
require('fs').writeFileSync(filename, media.b64, 'base64', function(err) {
if (err) throw err;
});
break;
}
}
}
}
}
My images come out fine, but the error is a little weird and I would prefer to not to occur. Would anyone have an idea as to why this is happening? That would be super helpful :)
Note: ReceivedMedia is a class I defined as:
function ReceivedMedia(media) {
this.b64 = media.b64;
this.extension = media.extension;
this.posx = media.posx;
this.posy = media.posy;
}
Side question: If I use writeFile instead of writeFileSync one of my images is corrupted and the other contains no data. If after that happens I run my node script again, the files save correctly. I would also like some explanation as to why that happens, from my understanding one of these is synchronous (writeFileSync I am guessing) and the other is asynchronous (writeFile I am assuming).
A Google search for your error message description found this discussion of the issue in io.js and this discussion in node.js and it sounds like it is a bug that has been fixed (not sure if the fix has been released in a full build yet).
The node.js fix is here.
If you were desparate to fix it now in your own build, you'd have to apply the fix to your own code tree and rebuild it. Otherwise, you'll have to investigate or inquire when this fix will get into an official release (I'm not personally sure how that process works for node.js).