I have imorted a module that performs a function on an array of data. When I run the function I get the results in my server but they seem not to be stored in my variable, which comes back undefined. Can someone tell me why my array comes back undefined when I can see the array in my server?
var net = require('net');
var foo = require('./employeeModule');
var _ = require('underscore');
var colors = require('colors/safe');
var server = net.createServer(
function(socket){
console.log("Client connection...");
socket.on('end', function(){
console.log("Client disconnected...");
});
// process data from client
socket.on('data', function(data){
var command = data.toString();
var results={};
console.log("Received Command: " +command);
if (command == "lookupByLastName Smith")
{
function lastName(results)
{
var results = foo.lookupByLastName('Smith');
console.log('These are the results: '+ results)
}
lastName();
}
else if (command == "addEmployee William Smith")
{
function addEmp(results)
{
var results = foo.addEmployee('William', 'Smith');
console.log('These are the results: '+ results)
}
addEmp();
}
else if (command == "lookupById 4")
{
function lookId(results)
{
var results = foo.lookupById(4);
console.log('These are the results: '+ Name)
}
lookId();
}
else if (command == "bye")
client.end();
else console.log(colors.green("**"+command+" Command not recognized!**"));
});
});
//listent for client connections
server.listen(1000, function(){
console.log("Listening for client connections");
});
First, what is wrong with your code:
var results={}: the var results is not used.
you have 3 functions lastName, addEmp and lookId. All are called and nothing is passed, therefore the results var is always undefined.
inside every of those functions you are defining another var results, so, nothing is done with the results parameter (like overwriting it).
in lookId the var Name it is undefined.
I suppose that you have the parameters hardcoded (commands, like William Smith, 4 or Smith) because it is some type of "test"/learning exercise. I would not recommend you to define the 3 functions inside the callback function (because they are defined every time it is called the callback).
If you want to keep the results do this (following your type of coding):
function addEmp(){
var res = foo.addEmployee('William', 'Smith');
console.log("There asre the results: " + res);
return res;
}
results = addEmp(); // now you set the value to results
Following more or less what would you do, I would do something like (be careful, I change a bit the type of coding and boundaries/inputs are not controlled):
function lastName(surname){
return foo.lookupByLastName(surname);
}
function addEmp(name, surname){
return foo.addEmployee(name, surname);
}
// ...
function socketData(data){
var args = data.toString().split(' '); // assuming space as splitter
var results;
var command = args[0];
switch(command){
case 'lookupByLastName':
results = lastName(args[1]);
break;
case 'addEmp':
results = addEmp(args[1], args[2]);
break;
default:
// ...
}
// do something with results
}
var server = net.createServer(function(socket){
// ...
socket.on('data', socketData);
// ...
});
Related
I'm looking for a AngularJS-based way to prevent multiple submits per task.
I don't need buttons to be disabled after submission or close the form and wait for the task to be completed. Instead, I need requests to be unique.
To be more detailed, I need $http.get and $http.post stop sending multiple same requests.
Any Ideas?
According to this article, you can use provider decorator.
NOTE: this approach is based on angular-api
https://gist.github.com/adambuczynski/354364e2a58786e2be71
UPDATE
I've changed a little part in your suggested solution, because returned promises have lost .success and .error and .then.
Just use this edited code to have all of those functions working:
.config(["$provide", function ($provide) {
$provide.decorator('$http', function ($delegate, $q) {
var pendingRequests = {};
var $http = $delegate;
function hash(str) {
var h = 0;
var strlen = str.length;
if (strlen === 0) {
return h;
}
for (var i = 0, n; i < strlen; ++i) {
n = str.charCodeAt(i);
h = ((h << 5) - h) + n;
h = h & h;
}
return h >>> 0;
}
function getRequestIdentifier(config) {
var str = config.method + config.url;
if (config.data && typeof config.data === 'object') {
str += angular.toJson(config.data);
}
return hash(str);
}
var $duplicateRequestsFilter = function (config) {
if (config.ignoreDuplicateRequest) {
return $http(config);
}
var identifier = getRequestIdentifier(config);
if (pendingRequests[identifier]) {
if (config.rejectDuplicateRequest) {
return $q.reject({
data: '',
headers: {},
status: config.rejectDuplicateStatusCode || 400,
config: config
});
}
return pendingRequests[identifier];
}
pendingRequests[identifier] = $http(config);
$http(config).finally(function () {
delete pendingRequests[identifier];
});
return pendingRequests[identifier];
};
Object.keys($http).filter(function (key) {
return (typeof $http[key] === 'function');
}).forEach(function (key) {
$duplicateRequestsFilter[key] = $http[key];
});
return $duplicateRequestsFilter;
})
}])
It could be a performance issue but following idea could solve your problem.
Store the each request URL and DATA as key value pair on a variable. URL should be KEY. For Same URL multiple submission can be stored in a Array.
Then for any new call check the URL if it present in your stored object, then compare the data with each object thorughly (deep check, it is costly though).
If any exact match found then stop the processing. As same request came.
Other wise proceed and don't forget to store this data also.
But it is costly since need to check the data which could be havy.
Note: At the time of storing the data you could convert it to JSON String so it will be easier to compare between String.
here is the Code Algo
YourService.call(url, params) {
var Str1 = JSON.stringify(params);
if(StoredObj[url]) {
for each (StoredObj[url] as Str){
if(Str === Str1) {
return;
}
}
}
else {
StoredObj[url] = []; //new Array
}
StoredObj[url].push(Str1);
Call $http then;
}
I have an array from my API that prints like this:
Array [Object, Object, Object, Object, Object]
// if stringified
[{"id":"0","name":"user1","type":"mf","message":"bonjour user1"},
{"id":"1","name":"user2","type":"ff","message":"hello user2"},
{"id":"2","name":"user3","type":"mm","message":"konnichiwa user3"},
{"id":"3","name":"user4","type":"mf","message":"ni hao user4"},
{"id":"4","name":"user5","type":"ff","message":"high 5! user5"}]}
I have an input named content and I would like to see if it matches any of the name in the array; if it does, which id is it; if it's not, the id would be 0.
Eg. if user enters user3, the id would be 2; and if user enters user9, the id would be 0.
I have been struggling to get the value of name from this nested array and below is what I have tried... and the whole code is here. It would be very nice if someone could tell me where have I done wrong:
var data = {};
$.ajax({
url: googleApi,
headers: {
"Authorization": "Basic " + btoa(googleKey + ":" + googleSecret)
},
data: data,
dataType: 'json',
type: 'GET',
success: function(data) {
console.log(data);
console.log(JSON.stringify(data));
function getID(name){
if (name.name == content){
console.log ("matching name" + name.name);
return getID(name.name);
} else {
return name;
}
}
alert(getID(data).id);
return false;
},
error: function(data) {
console.log("ERROR: " + data);
}
});
Updated Answer:
Dont alert the function, just alert the answer inside the loop when it matched.
I typed alexis in the textbox and the output was 1
I have edited my answer.Check it, this is what you have to do in your case:
function getID(name) {
$.each(data,function(key,value){
$.each(value,function(key1,value1){
console.log(value);
if(value1 == content){
alert(value.id);
return;
}
});
});
}
getID(data);
return false;
Take a look at the updated fiddle Fiddle Example
Second Update:
You do not have to use else if condition, simply use a variable to check whether there has been any matches.
You create a empty variable and while looping through the array check whether there is a match and if there is a match, you just feed the variable with that id value and later you will check whether the variable is empty or not and based on that alert(0);
Checkout the Latest Updated Fiddle
As you are using jQuery, you can use the grep function which is intended for searching an array:
var contentArray = [{"id":"0","name":"user1","type":"mf","message":"bonjour user1"},
{"id":"1","name":"user2","type":"ff","message":"hello user2"},
{"id":"2","name":"user3","type":"mm","message":"konnichiwa user3"},
{"id":"3","name":"user4","type":"mf","message":"ni hao user4"},
{"id":"4","name":"user5","type":"ff","message":"high 5! user5"}];
var input = 'user5';
var result = $.grep(contentArray, function(e){ return e.name == input; });
The result is an array with the items found. If you know that the object is always there and that it only occurs once, you can just use result[0].id to get the value. Otherwise you should check the length of the resulting array. Example:
if (result.length === 0) {
// not found
} else if (result.length === 1) {
// access the name property using result[0].id
} else {
// multiple items found
}
So you can design a function for above as per your requirement, something like below:
function getID(myArr, inputName) {
var result = $.grep(myArr, function(e){ return e.name == inputName; });
if (result.length === 0) {
return 0;
} else if (result.length === 1) {
return result[0].id
} else {
// multiple items found
// May be it's not true in your case
return result[0].id
}
}
I would like to know how I can obtain an obtain an objects item(LicenseNo) from an observable array. I have pasted my code below , after inserting breakpoints I noticed that I am currently getting the entire objects array as in [LicenseNo , name , allocated route , licenseDate] I just want to get the LicenseNo
function getDriverList(item) {
if (!pageViewModel.isAuthenticated()) return;
var dfd = jQuery.Deferred();
var LicenseNo = ko.observableArray([]);
$.when(getSecureData("/api/FleetDrivers/" + item.NationalID))
.done(function (resp) {
pageViewModel.vehicelDriversVM.DriverList(resp.FleetDriverList);
if (pageViewModel.vehicelDriversVM.DriverList(resp.FleetDriverList).length > 0) {
LicenseNo = pageViewModel.vehicelDriversVM.FleetDriverList()[0];
alert('The first driver's License Number is ' LicenseNo;
}
});
return dfd.promise();
}
the code above didnt work so I have pasted the correct one below for anyone who might run into a similar prob
function getDriverList(item) {
if (!pageViewModel.isAuthenticated()) return;
var dfd = jQuery.Deferred();
var LicenseNo = ko.observableArray();
$.when(getSecureData("/api/FleetDrivers/" + item.NationalID))
.done(function (resp) {
pageViewModel.vehicelDriversVM.DriverList(resp.FleetDriverList);
LicenseNo = resp.FleetDriverList[1];
alert('The first driver's License Number is ' + LicenseNo);
});
return dfd.promise();
enter code here
Is there a way how to check whether an element has any text in it? I already found textToBePresentInElement but this function checks for specified value and does not return a proper error if it fails.
I'm population the element via API and it's loaded bit later, so I want the browser to wait till any information appears in the element and then check for correct value.
Alternatively it would be also very helpful to manage to get a specific error message when EC fails:
browser.wait(EC.textToBePresentInElement(element(by.binding('myvar')), "expected"), 5000);
The third argument to browser.wait() is a custom error message:
browser.wait(EC.textToBePresentInElement(element(by.binding('myvar')), "expected"), 5000, "Text is not something I've expected");
See also:
Custom message on wait timeout error
To wait for an element to contain any text, you can write a custom expected condition:
var EC = protractor.ExpectedConditions;
var anyTextToBePresentInElement = function(elementFinder) {
var hasText = function() {
return elementFinder.getText().then(function(actualText) {
return actualText;
});
};
return EC.and(EC.presenceOf(elementFinder), hasText);
};
And here is the usage:
browser.wait(anyTextToBePresentInElement(element(by.binding('myvar'))), 5000);
The previous code snippet works form but with a small update: return actualText; should be boolean. So the whole code will be:
var anyTextToBePresentInElement = function(elementFinder) {
var EC = protractor.ExpectedConditions;
var hasText = function() {
return elementFinder.getText().then(function(actualText) {
return !!actualText;
});
};
return EC.and(EC.presenceOf(elementFinder), hasText);
};
Usage example:
var el = element(by.binding('myvar'));
browser.wait(anyTextToBePresentInElement(el, 5000, 'Element still has no text');
You can check this one
export function titleType(textReference, expectedText)
{
textReference.then(function(name)
{
if (name == expectedText)
{
expect(textReference).toContain(expectedText);
expect(name).toEqual(expectedText);
}
else
{
throw new TypeError("Wrong " + expectedText + " name " + name);
}
});
}
I'm having trouble decorate the objects in my list returned by $asArray in angularfire with a new method (not decorating the array itself).
The angularfire documentation seems to suggest that the right way to do this is to override the $$added method in the factory for $FirebaseArray, returning a new object that either encapsulates or extends the snapshot that gets passed in to that method. From the documentation:
// an object to return in our JokeFactory
app.factory("Joke", function($firebaseUtils) {
function Joke(snapshot) {
this.$id = snapshot.name();
this.update(snapshot);
}
Joke.prototype = {
update: function(snapshot) {
// apply changes to this.data instead of directly on `this`
this.data = snapshot.val();
},
makeJoke: function() {
alert("Why did the " + this.animal + " cross the " + this.obstacle + "?");
},
toJSON: function() {
// since we didn't store our data directly on `this`, we need to return
// it in parsed format. We can use the util function to remove $ variables
// and get it ready to ship
return $firebaseUtils.toJSON(this.data);
}
};
return Joke;
});
app.factory("JokeFactory", function($FirebaseArray, Joke) {
return $FirebaseArray.$extendFactory({
// change the added behavior to return Joke objects
$$added: function(snap) {
return new Joke(snap);
},
// override the update behavior to call Joke.update()
$$updated: function(snap) {
this.$getRecord(snap.name()).update(snap);
}
});
});
However, when I do this in my code, nothing ever gets added to the array, although I can see from outputting to the console that it is getting called.
var printMessageObjConstructor = function(snap) {
this.$id = snap.name();
this.snapshot = snap;
this.$update = function(snap) {
this.snapshot = snap;
};
this.printMessage = function() {
return this.author + "'s question is: " + this.body;
};
};
var ref = new Firebase("https://danculley-test.firebaseio.com/questions");
//What Am I Doing Wrong Here?
var arrayFactory = $FirebaseArray.$extendFactory({
$$added: function(snap, prevChild) {
var x = new printMessageObjConstructor(snap);
console.log("I am being called from FirebaseDecoratedCtlOverloadAddedinNewObj.");
return x;
},
$createObject: function(snap) {
return new printMessageObjConstructor(snap);
},
$$updated: function(snap) {
var i = this.$indexFor(snap.name());
var q = this.$list[i];
q.$update(snap);
}
});
var sync = $firebase(ref, {arrayFactory:arrayFactory});
var list = sync.$asArray();
list.$loaded(function(list) {
$scope.questions = list;
});
I've set up a new plunk stripped down to show the issue with a couple other use cases that I've tried. (The actual method I'm adding is more complex and isn't related to the view, but I wanted to do something simple to reproduce the issue.)
I think the issue is that I don't quite understand what exactly $$added is supposed to return, or what additional behavior beside returning the value to be stored $$added is supposed to have. There also doesn't really seem to be an $$added on the prototype or on $FirebaseArray to call as a super to get the default behavior. Can someone point me in the right direction?
UPDATE
For the benefit of others, after reviewing the like that Kato posted, I was able to solve the issue by adding the following, almost all copied directly from the source except for the commented line below.
$$added: function(snap, prevChild) {
var i = this.$indexFor(snap.name());
if( i === -1 ) {
var rec = snap.val();
if( !angular.isObject(rec) ) {
rec = { $value: rec };
}
rec.$id = snap.name();
rec.$priority = snap.getPriority();
$firebaseUtils.applyDefaults(rec, this.$$defaults);
//This is the line that I added to what I copied from the source
angular.extend(rec, printMessageObj);
this._process('child_added', rec, prevChild);
}
}
For the benefit of others, after reviewing the link that Kato posted, I was able to solve the issue by adding the following, almost all copied directly from the source except for the commented line below.
$$added: function(snap, prevChild) {
var i = this.$indexFor(snap.name());
if( i === -1 ) {
var rec = snap.val();
if( !angular.isObject(rec) ) {
rec = { $value: rec };
}
rec.$id = snap.name();
rec.$priority = snap.getPriority();
$firebaseUtils.applyDefaults(rec, this.$$defaults);
//This is the line that I added to what I copied from the source
angular.extend(rec, printMessageObj);
this._process('child_added', rec, prevChild);
}
}