event emitting when trying to fetch data - javascript

I am trying to create two node.js files. I am using event emitter module. When ever i try to search through the data i want to emit an event so that event is raised before my data is returned from the array of objects.
// event emitter file:
var EventEmitter = require('events').EventEmitter;
var inherits = require('util').inherits;
var _ = require('underscore');
// Custom class
function EmployeeEmitter(args) {
this.data = args;
EventEmitter.call(this);
}
inherits(EmployeeEmitter, EventEmitter);
EmployeeEmitter.prototype.lookupByLastName = function (name) {
this.emit('lookupByLastName',name);
if( _.where(data, {lastName:name}))
{
return _.where(data, {lastName:name})
}
else{
return;
}
};
module.exports.EmployeeEmitter = EmployeeEmitter;
Now this is my event emitter which i want to fire lookupbylastName when the user searches through the data. For testing it i have created another file where i am using event.on method.Unfortunately its' not running it gives me error i dont know wats going wrong.
//Test file:
var colors = require('colors');
var EmployeeEmitter = require('./employeeEmitter').EmployeeEmitter;
// Usage
var data = [
{id:1, firstName:'John',lastName:'Smith'},
{id:2, firstName:'Jane',lastName:'Smith'},
{id:3, firstName:'John',lastName:'Doe'}
];
var employees = new EmployeeEmitter(data);
employees.on('lookupByLastName', function (args) {
});
console.log("\nLookup by last name (Smith)".red);
console.log(employees.lookupByLastName('Smith'));

Related

calling a function object to load your js

function FriendlyChat() {
// statements
}
FriendlyChat.protoype.somemethod = function() {
// statements
};
FriendlyChat.protoype.somemethod2 = function() {
//statements
};
window.onload = function() {
window.friendlyChat = new FriendlyChat();
};
So i noticed the above structure for js while working on a google codelab.
And I have two ques.
in normal objects you have to call the function i.e Object.somemethod()
How does this structure call the methods assigned to it.
From my limited understanding, Firendlychat.protoype.the method treats the
function as an object and the methods are passed to the new object created on
window.onload.Via
inheritance, The object created i.e friendlychat has all these methods.
Yet none of the methods are called in any way. How does this work?
Is there any advantage to structuring your code in this way other than
readability
Note :
Main function
function FriendlyChat() {
this.checkSetup();
// Shortcuts to DOM Elements.
this.messageList = document.getElementById('messages');
this.messageForm = document.getElementById('message-form');
// Saves message on form submit.
this.messageForm.addEventListener('submit', this.saveMessage.bind(this));
this.signOutButton.addEventListener('click', this.signOut.bind(this));
this.signInButton.addEventListener('click', this.signIn.bind(this));
// Toggle for the button.
var buttonTogglingHandler = this.toggleButton.bind(this);
this.messageInput.addEventListener('keyup', buttonTogglingHandler);
this.messageInput.addEventListener('change', buttonTogglingHandler);
// Events for image upload.
this.submitImageButton.addEventListener('click', function(e) {
e.preventDefault();
this.mediaCapture.click();
}.bind(this));
this.mediaCapture.addEventListener('change',
this.saveImageMessage.bind(this));
this.initFirebase();
}
//the methods are setup here
// Sets up shortcuts to Firebase features and initiate firebase auth.
FriendlyChat.prototype.initFirebase = function() {
this.auth = firebase.auth();
this.database = firebase.database();
this.storage = firebase.storage();
// Initiates Firebase auth and listen to auth state changes.
this.auth.onAuthStateChanged(this.onAuthStateChanged.bind(this));
};
// Saves a new message on the Firebase DB.
FriendlyChat.prototype.saveMessage = function(e) {
e.preventDefault();
}
};
FriendlyChat.prototype.setImageUrl = function(imageUri, imgElement) {
imgElement.src = imageUri;
};
// Saves a new message containing an image URI in Firebase.
// This first saves the image in Firebase storage.
FriendlyChat.prototype.saveImageMessage = function(event) {
event.preventDefault();
var file = event.target.files[0];
// Clear the selection in the file picker input.
this.imageForm.reset();
// Check if the file is an image.
if (!file.type.match('image.*')) {
var data = {
message: 'You can only share images',
timeout: 2000
};
this.signInSnackbar.MaterialSnackbar.showSnackbar(data);
return;
}
// Check if the user is signed-in
if (this.checkSignedInWithMessage()) {
// TODO(DEVELOPER): Upload image to Firebase storage and add message.
}
};
// Signs-in Friendly Chat.
FriendlyChat.prototype.signIn = function() {
var provider = new firebase.auth.GoogleAuthProvider();
this.auth.signInWithRedirect(provider);
};
// Signs-out of Friendly Chat.
FriendlyChat.prototype.signOut = function() {
this.auth.signOut();
};
One of the advantages I've seen when using prototype inheritance was that you can control all instances of an object. For ex:
function FriendlyChat() {
this.chatIsActive = true;
}
FriendlyChat.prototype.deactivateChat = function(...rooms) {
for (chatRoom of rooms) {
chatRoom.chatIsActive = false;
}
};
var chat1 = new FriendlyChat();
var chat2 = new FriendlyChat();
var chatController = new FriendlyChat();
chatController.deactivateChat(chat1, chat2)
console.log(chat1.chatIsActive)
In ES6, however, you can do it:
class FriendlyChat {
constructor() {
this.chatIsActive = true;
}
static deactivateChat(...rooms) {
for (let chatRoom of rooms) {
chatRoom.chatIsActive = false;
}
}
}
var chat1 = new FriendlyChat();
var chat2 = new FriendlyChat();
FriendlyChat.deactivateChat(chat1, chat2)
console.log(chat1.chatIsActive)
And the another advantage of using prototype is that you can save memory spaces when you make an object from new keyword. For instance, the code in ES5 above, you can see chat1 and chat2 I've made by using new. Then chat1 and chat2 will be able to access deactivateChat() method which is in a sharing-space. It's because of the concept, called prototype-chaining.
And the next ES6 version is just a syntactic sugar - under the hood it does the same as ES5 version
I post this as a reference to others who have been faced with this dilemma.
First of all, ONe of the core issues for me was migrating from java, I seemed to be familiar territory but things work a bit different in js.I strongly recommend these links:
Objects in Detail
js Prototype
So the key to why this method works is due to the
window.friendlyapp =new friendlychat()
Now normally in most languages you have an object
obj() {
attr : value
method: function() {}
}
And then to use the method you do
var child = new obj();
child.method();
but in this method the var is made an instance of the window object and thats why none of the methods of the app need to be explicitly called.

Object.keys() not working in class

I have a class which reads a LokiJS database upon initialization and saves the database in an object, whereby a collection corresponds to a name. I want to have a separate array which holds just the names. I would normally do this with Object.keys(obj), but in my case that returns an empty array.
The code I so far have is:
class Barbot extends EventEmitter{
constructor(HOST, PORT, ioUID, lcUID) {
super();
var self = this;
// lokijs databases
this.dbCocktails = new loki('./src/JavaScript/Cocktails.json');
this.dbBottles = new loki('./src/JavaScript/Bottles.json');
//parameters
this.cocktails = {};
this.cocktailNames = [];
async.parallel({
db1 : function(callback){
self.dbCocktails.loadDatabase({}, function(){
callback(null);
});
},
db2 : function(callback){
self.dbBottles.loadDatabase({}, function(){
callback(null);
});
}
}, function(err, results) {
// initialize some objects
self.bottles = self.dbBottles.getCollection('Flaschen');
var cocktailArray = self.dbCocktails.listCollections();
for (let i = 0; i < cocktailArray.length; i++) {
self.cocktails[cocktailArray[i].name] = self.dbCocktails.getCollection(cocktailArray[i].name);
}
self.cocktailNames = Object.keys(self.cocktails); // somehow that doesn't work here!
})
}
This class is then imported from a normal JS-script which is run from a node-webkit app (is this maybe the problem? Does HTML have a problem with the class definition?). So that when I initialize this class and then log the Barbot.cocktails and Barbot.cocktailNames, the cocktails is what I would expect but the cocktailNames are empty. When I run the same code outside of a class, everything works as it should and the array of the names is filled with the names of my cocktails. Can someone help me figure out where my problem lies??
Edit: Here's the Code I use to initiate the class:
var Bb = require('./src/JavaScript/BarbotClass');
var HOST = 'localhost',
PORT = 4223,
ioUID = "wjY",
lcUID = "vbn";
var Barbot = new Bb(HOST, PORT, ioUID, lcUID);
console.log(Barbot)
console.log(Barbot.cocktailNames); // Array[0]
second Edit:
So when I log the Barbot object from this everything seems to be initialized just fine. But when I try to access parameters, they seem not to be the right ones. E.g. it looks like it would access the protoype of the parameters?? I included a picture of how the console output looks like.

Cloud Code function not saving data

Before putting this on the cloud code I tested it in Angular with success producing the correct console.log responses throughout the program. Since this function manipulates data in the user table it must use the master key and be in cloud code. With this code in the cloud it saves the column 'duty' to the user table but with no data (there is data to be saved, this I am sure of). Moreover, I'm not even sure that the code runs past the first Parse Query as the console.log returns nothing in the Parse Logs. Where am I going wrong?
'use strict';
var express = require('express');
var app = express();
app.use(express.bodyParser());
var _ = require('underscore');
var server = require('http').createServer(app);
Parse.Cloud.define("updateMerchant", function(request, response) {
Parse.Cloud.useMasterKey();
var user = Parse.Object.extend("User")
var merchantQuery = new Parse.Query(Parse.User);
var Offers = Parse.Object.extend("Offer");
var offerQuery = new Parse.Query(Offers);
var Matches = Parse.Object.extend("Matched");
var matchQuery = new Parse.Query(Matches);
var merchantDuty = [];
var merchants = request.params.data;//I confirmed the validity of this a key value pair where the value is an array of objects.
var merchantIds = _.map(merchants, function(n){return n.id});
console.log(merchantIds)
offerQuery.containedIn("user", merchants);
offerQuery.limit(1000);
offerQuery.find({//CODE STOPS RUNNING?!?
success: function (offers) {
var offerIds = _.map(offers, function (n) {
return n.id});
console.log(offers)//this is telling as it does not appear in the Parse log!
var offersBeta = _.map(offers, function (n) {
return _.extend(_.find(n), {id: n.id})});
matchQuery.containedIn("offer", offers);
matchQuery.limit(1000);
matchQuery.find({
success: function (matches) {
var merchantArray = _.map(_.flatten(matches), function (n) {return _.find(n)});
var offers3 = _.map(offersBeta, function (n) {return _.extend(n, {
Matched: _.filter(merchantArray, function (a) {return a.offer.id == n.id})})})
var duty = function (TotalBill, id) {
var promise = new Parse.Promise();
merchantQuery.get(id, {
success: function (merchantBill) {
merchantBill.set("duty", TotalBill);
merchantBill.save().then(function(obj){ console.log(obj); }, function(error){console.log(error)})}})}
merchantDuty.push(duty(_.map(offer9, function(n){return n.TotalBill}), _.map(offer9, function(n){return n.id})));
},
error: function(){console.log(error);
}
})
}
})
//Code begins running again!
return Parse.Promise.when(merchantDuty).then(function() {
response.success("Success");
},
function(error) {response.error("Something is still wrong");
console.log(error);})
})
To be more clear, nothing between offerQuery.find and return Parse.Promise is run.
You need to pass pointers in offerQuery.containedIn("user", merchants);. See this.
Try this:
var _ = require('underscore');
Parse.Cloud.define("updateMerchant", function(request, response) {
Parse.Cloud.useMasterKey();
var merchantDuty = [];
var merchants = request.params.data;//I confirmed the validity of this a key value pair where the value is an array of objects.
// var merchantIds = _.map(merchants, function(n) {return n.id;});
// console.log(merchantIds);
// Since I don't have the merchants request parameter, I'll fake it with some fake users
var fakeMerchants = [{"username":"Batman","objectId":"f7zZkPx7kT","createdAt":"2015-04-07T19:41:25.014Z","updatedAt":"2015-04-07T19:41:25.014Z","__type":"Object","className":"_User"},{"username":"Robin","objectId":"wgG4EfaFN1","createdAt":"2015-04-07T19:41:35.024Z","updatedAt":"2015-04-07T19:41:35.024Z","__type":"Object","className":"_User"}];
// We can get some users like this:
// var fakeMerchantsQuery = new Parse.Query(Parse.User);
// fakeMerchantsQuery.find().then(function(users) {
// console.log(users);
// });
// Since the 'user' column in Offer Class is a pointer, we need to pass merchant pointers.
// Otherwise we get the error "pointer field user needs a pointer value"
// See https://www.parse.com/questions/using-containedin-with-array-of-pointers
var fakeMerchantsPointers = _.map(fakeMerchants, function(merchant) { // TODO change to real merchants
var pointer = new Parse.User();
pointer.id = merchant.objectId;
return pointer;
});
console.log(fakeMerchantsPointers);
var offerQuery = new Parse.Query(Parse.Object.extend("Offer"));
offerQuery.containedIn("user", fakeMerchantsPointers); // TODO change to real merchants
offerQuery.limit(1000);
offerQuery.find().then(function(offers) {
console.log("inside offer query");
console.log(offers);
// Here I assume that the column 'offer' is a Pointer
var matchQuery = new Parse.Query(Parse.Object.extend("Matched"));
matchQuery.containedIn("offer", offers);
matchQuery.limit(1000);
return matchQuery.find();
}).then(function(matches){
console.log("inside matches query");
console.log(matches);
// Add the duty stuff here...
// We must call success or error
response.success("Success");
});
});
Let me know if it worked.
Please note that you shouldn't mix Cloud Code with ExpressJS code. The Cloud Code should be in main.js, and the ExpressJS code in app.js. Then, in Cloud Code main.js call require('cloud/app.js'); if you want the request pass through ExpressJS.
The line return Parse.Promise.when(merchantDuty) is executing before there are any promises in the merchantDuty array (initialized as empty).
So the whole function is terminating before your query find success function.
I think if you create and add query promises to the merchantDuty array you will fix your bug.
I also suggest you to use promise callbacks for the query methods. Like:
query.find().then(function(){
//success
}, function(error){
//error
});
You can then chain them by returning another promise and make the code better structured.

React-Flux: Error with AppDispatcher.register

I am trying to set up the most basic app in Flux-React. Its sole goal to is fire an Action, which gets sent through the Dispatcher to a Store that has registered with the Dispatcher. The store the logs the payload to Console.
Everything besides the Store is working well, but as soon as it hits AppDispatcher.register, Flux throws the following error:
Uncaught TypeError: Cannot set property 'ID_1' of undefined
Here is the code of the file causing the error, but I've put up the entire project at https://github.com/bengrunfeld/react-flux-dispatcher-error, and you can find the offending file in src/js/stores/AppStores.js
var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var AppConstants = require('../constants/AppConstants');
var assign = require('object-assign');
var CHANGE_EVENT = 'change';
var AppStore = assign({}, EventEmitter.prototype, {
emitChange: function() {
this.emit(CHANGE_EVENT);
}
});
AppDispatcher.register(function(payload){
console.log(payload);
return true;
})
module.exports = AppStore;
Because of the drought of documentation of biblical proportions for Facebook Flux, I didn't know that I was using code from previous versions.
In AppDispatcher.js, you need to define AppDispatcher in the following way using the new keyword:
var Dispatcher = require('flux').Dispatcher;
var assign = require('object-assign');
var AppDispatcher = assign(new Dispatcher(), {
handleViewAction: function(action) {
this.dispatch({
source: 'VIEW_ACTION',
action: action
});
}
});
module.exports = AppDispatcher;
Here is a link to a repository with the working code: https://github.com/bengrunfeld/react-flux-simple-app

Javascript: inheriting encapsulated variables

Edit: Removed higher-level ideas, included problem-specific and less-transferable code.
I implemented my DAL using DAO's. My application hooks in to various databases (mostly for legacy reasons). In order to facilitate efficient and intelligent usage of connections, I use a ConnectionBroker singleton to manage the various connections that may (or may not be) open. This ConnectionBroker is then injected into the DAO's where they can request control of a particular connection object, request new connections, ect.
From an inheritence POV, I'd like something like:
AbstractDbConnection
|-- MongoDbConnection
|-- MsSqlConnection
|-- CouchDbConnection
|-- ...
Where AbstractDbConnection defines an interface, and implements some shared event-based logic.
var EventEmitter = require('events').EventEmitter;
module.exports = function AbstractDbConnection(host, port, database, login, ...) {
// private
var state = StatesEnum.Closed; // StatesEnum = {Open: 0, Closed: 1, ..}; Object.freeze(StatesEnum);
// api that must be overwritten
this.connect = function connect() {throw new ...}
this.disconnect = function disconnect() {throw new ...}
... <more>
this.getState = function() { return state; }
}
AbstractDbConnection.prototype.__proto__ = EventEmitter.prototype;
And then I implement the interface using driver-specific code:
var mssqldriver = require('mssqldriver'), //fictitious driver
AbstractDbConnection = require(__dirname + '/blah/AbstractDbConnection');
module.exports = function MsSqlConnection(host, port, database, login, ...) {
var me = this;
// implement using driver
this.connect = function connect() {...}
this.disconnect = function disconnect() {...}
... <more>
driverSpecificConnection.on('driverSpecificOpenEvent', function() {
me.emit('open'); // relay driver-specific events into common events
state = StatesEnum.Open; // how ??
}
...
}
MsSqlConnection.prototype.__proto__ = new AbstractDbConnection();
But clearly I want to protect the state property from changing inadvertently.
Just listen for the open event in the "abstract" constructor!
var EventEmitter = require('events').EventEmitter;
module.exports = AbstractDbConnection;
var StatesEnum = module.exports.StatesEnum = Object.freeze({
Open: 0, Closed: 1, …
});
function AbstractDbConnection(host, port, database, login, …) {
// private
var state = StatesEnum.Closed;
EventEmitter.call(this);
this.getState = function() { return state; }
this.on('open', function(e) {
state = StatesEnum.Open;
});
}
AbstractDbConnection.prototype = Object.create(EventEmitter.prototype);
// api that must be overwritten
AbstractDbConnection.prototype.connect = function connect() {throw new …};
AbstractDbConnection.prototype.disconnect = function disconnect() {throw new …};
var Mssqldriver = require('mssqldriver'), //fictitious driver
AbstractDbConnection = require(__dirname + '/blah/AbstractDbConnection');
module.exports = MsSqlConnection;
function MsSqlConnection(host, port, database, login, …) {
AbstractDbConnection.call(this);
this.driver = new Mssqldriver(…);
this.driver.on('driverSpecificOpenEvent', this.emit.bind(this, 'open'));
…
}
MsSqlConnection.prototype = Object.create(AbstractDbConnection.prototype);
MsSqlConnection.prototype.connect = function connect() {…};
MsSqlConnection.prototype.disconnect = function disconnect() {…};
You can use the module pattern to do this.
var transport_module = function() {
var mileage = 0; // private
return {
transport : function(distance) {
mileage += distance;
}
};
}
//use it
var car = transport_module(),
boat = transport_module(),
motorcycle = transport_module();
car.transport(10);
boat.transport(5);
motorcycle.transport(20);
The variable mileage is not visible to any other javascript code. Like a private java/C++ class variable. However, I would think about whether you need this kind of protection. I use modules a lot but not for small objects like class instances in java/C++.

Categories

Resources