So im trying to automaically retrieve a random entry from an array listed in a seperate node.js file
function code
var replies = require('./replies');
function followed(event) {
var name = event.source.name;
var flname = event.source.screen_name;
var myArray = [replies];
var item = myArray[(Math.random()*myArray.length)|0];
var followtweet = '#' + flname + item;
if(flname != "UserName") {
tweetIt(followtweet);
console.log('\n#' + flname + ' Followed You');
console.log('\nYou Tweeted:\n ' + followtweet);
} else {
console.log(' Interferance From Another Bot! \n');
}
}
External Array
module.exports = {
followedone: 'one',
followedtwo: 'two',
followedthre: 'three',
replyone: ' one',
replytwo: ' two',
replythre: ' three',
}
When I Run This and the function runs i get this
#LandscapesLucid Followed You
You Tweeted:
#LandscapesLucid[object Object]
Waiting For The Next Action
I'm not sure why its only showing the [object Object] instead of either one two or three like in the array
Can you try to change from this
var item = myArray[(Math.random()*myArray.length)|0];
to this?
var item = myArray[Math.floor(Math.random()*items.length)];
Related
I am trying to use textFinder to return the data from recordsSheet; I expect cslData[0] to return the employee ID number; however, it is returning the character in the 0 position of the string value.
function textFinder(findID){
var recordData;
var findRecord = recordsSheet.createTextFinder(findID);
var foundRange = findRecord.findNext();
var fRng = recordsSheet.getRange(foundRange.getRow(),1,1,9)
while(null != foundRange){
recordData.push(fRng.getValues());
foundRange = findRecord.findNext();
}
return(recordData);
}
var ss = SpreadsheetApp.getActiveSpreadsheet();
var recordsSheet = ss.getSheetByName("Active Records");
function onFormSubmit(e) {
var eRng = e.range;
var eRow = eRng.getRow();
var colA = ss.getRange('A' + eRow).getValue()
//The second value of the form response (e) is in Column A
Logger.log("Call txt finder")
var cslData = textFinder(colA).toString().split(",").join();
Logger.log("cslData: " + cslData)
Logger.log("cslData[0]: " + cslData[0])
Logger.log("cslData[1]: " + cslData[1])
Logger.log("cslData[2]: " + cslData[2])
Logger.log("cslData[0][0]: " + cslData[0][0])
}
I was expecting cslData[0] to return "100###5"
Modification points:
In your script, eRow is not declared. And, e is not used. Please be careful about this. In this modification, it supposes that eRow is declared elsewhere.
In your script, var recordData; is not an array. So, I think that an error occurs at recordData.push(fRng.getValues());. So, I'm worried that your showing script might be different from your tested script.
If var recordData; is var recordData; = [], about your current issue, in your script, the array of recordData is converted to the string by var cslData = textFinder(colA).toString().split(",").join();. By this, cslData[0] returns the top character. I thought that this is the reason for your issue.
And, if var recordData; is var recordData; = [], recordData is 3 dimensional array.
In your situation, I thought that findAll might be useful.
When these points are reflected in your script, how about the following modification?
Modified script:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var recordsSheet = ss.getSheetByName("Active Records");
function textFinder(findID) {
return recordsSheet
.createTextFinder(findID)
.findAll()
.map(r => recordsSheet.getRange(r.getRow(), 1, 1, 9).getValues()[0]);
}
function onFormSubmit(e) {
var colA = ss.getRange('A' + eRow).getValue();
var cslData = textFinder(colA);
Logger.log("cslData: " + cslData);
if (cslData.length > 0) Logger.log("cslData[0]: " + cslData[0][0]);
}
or, I think that you can also the following script.
function onFormSubmit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var recordsSheet = ss.getSheetByName("Active Records");
var eRow = ###; // Please set this.
var findID = ss.getRange('A' + eRow).getValue();
var cslData = recordsSheet.createTextFinder(findID).findAll().map(r => recordsSheet.getRange(r.getRow(), 1, 1, 9).getValues()[0]);
Logger.log("cslData: " + cslData)
if (cslData.length > 0) Logger.log("cslData[0]: " + cslData[0][0])
}
Reference:
findAll()
based on this Mongoose embedded documents / DocumentsArrays id
i try to implement a condition in a loop inside a loop. At the end, the new "tosave" Comments Object should contain the _id from the BlogPost based on "where a_id = b_id".
I use node,express and mongoose.
I have a multi row form with multiple BlogPosts and a Blogpost can have multiple Comments.
On the Backend, i have 2 Arrays -> BlogPosts and Comments like this:
BlogPosts: [{ a_id: '1', name: 'name1' },
{ a_id: '2', name: 'name2' },
{ a_id: '3', name: 'name3' }],
Comments: [{ b_id: '1', name: 'comment for BlogPost name1' },
{ b_id: '1', name: 'other comment for BlogPost name1' },
{ b_id: '3', name: 'comment for BlogPost name3' }],
I need the _id from a Blogpost Document inside every Comment, to reference between Comments and Blogposts.
I loop over the BlogPosts like this:
var new_post_to_save = [];
for(var i=0; i<req.body.blogposts.length;i++) {
var newpost = new BlogPost();
console.log('blogpost nr : ' + [i] + ' has new _id: ' + newpost._id );
newpost.name = req.body.blogposts[i].name,
newpost.a_id = req.body.blogposts[i].a_id
new_post_to_save.push(newpost);
},
This is working fine. I get a new Array "new_post_to_save", witch i can save easy.
Now i try to loop inside BlogPosts to give every Comment the _id Field from the new created "newpost" Object.
What i try - but it failed.. It matches all Comments to all BlogPosts.
var new_post_to_save = [];
var new_comment_to_save = [];
for(var i=0; i<req.body.blogposts.length;i++) {
var newpost = new BlogPost();
console.log('blogpost nr : ' + [i] + ' has new _id: ' + newpost._id );
newpost.name = req.body.blogposts[i].name,
newpost.a_id = req.body.blogposts[i].a_id
// here a loop to create x Comments with the _id from newpost and
// the condition: IF a_id = b_id
// then create new Comment and get die _id from his Blogpost
for(var f=0; f<req.body.comments.length;f++) {
if (newpost.a_id = req.body.comments[f].b_id)
console.log(' Yea ! Comment ' + [f] + ' matches Blogpost Nr. ' + [i]);
var newcomment = new CommentModel();
newcomment.id_newpost = newpost._id,
newcomment.name = req.body.comments[f].name,
newcomment.b_id = req.body.comments[f].b_id,
}; // end if
}; // end for
new_comment_to_save.push(newcomment);
new_post_to_save.push(newpost);
}, // end for
This is my first question here.
Any ideas ? Thanks so much
I am not familair with Mongoose, just looking at your code, seems you have a little mistake in code: position of: new_comment_to_save.push(newcomment); it should be in the if because only when they match you want them added..
var new_post_to_save = [];
var new_comment_to_save = [];
for(var i=0; i<req.body.blogposts.length;i++) {
var newpost = new BlogPost();
console.log('blogpost nr : ' + [i] + ' has new _id: ' + newpost._id );
newpost.name = req.body.blogposts[i].name,
newpost.a_id = req.body.blogposts[i].a_id
// here a loop to create x Comments with the _id from newpost and
// the condition: IF a_id = b_id
// then create new Comment and get die _id from his Blogpost
for(var f=0; f<req.body.comments.length;f++) {
if (newpost.a_id = req.body.comments[f].b_id)
console.log(' Yea ! Comment ' + [f] + ' matches Blogpost Nr. ' + [i]);
var newcomment = new CommentModel();
newcomment.id_newpost = newpost._id,
newcomment.name = req.body.comments[f].name,
newcomment.b_id = req.body.comments[f].b_id,
new_comment_to_save.push(newcomment);
}; // end if
}; // end for
new_post_to_save.push(newpost);
}, // end for
How do you make the console print true when the variable "message" contains an element from each array in order: "greetings" then "colour" then "names", but any words before "greetings" and after "colour" still prints true.
If the elements are out of order it should print false.
If there are words in-between the elements it should print false.
Check examples below current code.
Current Code:
var message = '';
var greetings = 'hi' || 'hello' || 'hey';
var colour = 'red' || 'green' || 'blue';
var names = 'john' || 'evan' || 'etienne';
if (message.includes(greetings + ' ' + colour + ' ' + names)) {
console.log(true);
} else {
console.log(false);
}
Examples of what it should print when message:
message = 'hi green evan' //true
message = 'lol hey blue john' //true
message = 'hello green etienne! xD' //true
message = 'evan green hi' //false because wrong element order
message = 'hi very green evan' //false because word in-between elements
You can use regex for this.
var message = "hello green etienne! xD";
var greetings = ["hi", "hello", "hey"].join("|");
var colors = ["red", "green", "blue"].join("|");
var names = ["john", "evan", "etienne"].join("|");
var reg = new RegExp("^.*(" + greetings + ")\\s+.*(" + colors + ")\\s+(" + names + ").*$");
console.log(reg.test(message));
var message = 'hi green evan';
var greetings = ["hi","hello","hey"];
var colour = ['red','green','blue'];
var names = ['john','evan','etienne'];
var contained = false;
greetings.some(x =>{
colour.some(z=>{
names.some(e=>{
if(message.includes(x + ' ' + z + ' ' + e)){
contained = true;
alert(true);
}
});
});
});
if(!contained)
alert(false);
You could do it like this. Probably not the best way to do it but the first thing that came to my mind
Here I am using angular Tree for component. When the data is entering first time it is working fine.
But the data is coming from backend, then the adding row button is not adding.
Plunker
Here is my code.
$scope.newSubItem = function(scope) {
var nodeData = scope.$modelValue;
nodeData.items.push({
id: nodeData.items.length?(nodeData.items[nodeData.items.length-1].id)+1:nodeData.id * 10,
rowId: nodeData.rowId + '.' + ((nodeData.items.length?(parseInt(nodeData.items[nodeData.items.length-1].rowId.split('.').pop()))+1:1)),
items: []
});
};
The error is
TypeError: Cannot read property 'push' of null
at Scope.$scope.newSubItem (app.js:19)
at $parseFunctionCall (angular.js:12332)
at callback (angular.js:22949)
at Scope.$eval (angular.js:14383)
at Scope.$apply (angular.js:14482)
at HTMLAnchorElement.<anonymous> (angular.js:22954)
at HTMLAnchorElement.eventHandler (angular.js:3011)
Before pushing you need to initialize the array if its null,
nodeData.items = [];
$scope.newSubItem = function(scope) {
var nodeData = scope.$modelValue;
if(nodeData && nodeData.items ){
}
};
This is happening because when a node has no child elements you are not returning empty array in items from the server
Either add code on server side which adds an empty array in items
or
#Sajeetharan is right you need to add this code in your newSubItem function
$scope.newSubItem = function(scope) {
var nodeData = scope.$modelValue;
if(!nodeData.items)
nodeData.items =[];
nodeData.items.push({
id: nodeData.items.length?(nodeData.items[nodeData.items.length-1].id)+1:nodeData.id * 10,
rowId: nodeData.rowId + '.' + ((nodeData.items.length?(parseInt(nodeData.items[nodeData.items.length-1].rowId.split('.').pop()))+1:1)),
items: []
});
};
This problem has me stumped.
For some reason, the autoincrementing key generator in indexedDB resets after performing and update on an existing object with a put-transaction, leading to overwrites of data in the database.
For my app, I'm using a self written IndexedDB service for angularJS with all the basic CRUD functions implemented.
I may also add that I'm developing with Ionic Framework, even though I doubt that is to blame.
Considering the service is a work-in-progress, I've let the key path for an object store default to "id" with an autoincrementing strategy.
The indices for the given store, nevertheless, are up to the user to decide in a specific object.
As an example:
dbHelper.objectStores = [{'employees',
indices: [{indexName: 'name', isUnique: false},
{indexName: 'phone', isUnique: true}]}];
This would, unless already created in the db, create the object store 'employees' with indices 'name' and 'phone', where 'phone' would have to be a unique value while 'name' would not.
Here is the implementation of the openDB function.
Please note that dbHelper.objectStores is supposed to be empty as it's up to the user to assign these properties before opening the db(or else it is defaulted).
angular.module('dbProvider', [])
.factory('$db', ['$window', function($window) {
// DB Object
var dbHelper = {};
// Properties - Are given defaults unless assigned manually by user before openDB is invoked.
dbHelper.dbName = 'defaultDB';
dbHelper.dbVersion = 1;
dbHelper.objectStores = [];
dbHelper.openDB = function(onCompleteCallback, onErrorCallback) {
console.log('Atempting to open db with name ' + dbHelper.dbName + '.');
var request = $window.indexedDB.open(dbHelper.dbName, dbHelper.dbVersion);
// Invoked by indexedDB if version changes
request.onupgradeneeded = function(e) {
console.log('Version change. Current version: ' + dbHelper.dbVersion);
var db = e.target.result;
e.target.transaction.onerror = onErrorCallback;
if(dbHelper.objectStores.length === 0) {
dbHelper.objectStores.push({name:'defaultStore', indices: []});
}
for(var store in dbHelper.objectStores) {
if(db.objectStoreNames.contains(dbHelper.objectStores[store].name)) {
console.log(dbHelper.objectStores[store].name + ' deleted.');
db.deleteObjectStore(dbHelper.objectStores[store].name);
}
var newStore = db.createObjectStore(dbHelper.objectStores[store].name, {keyPath: "id", autoIncrement: true});
for(var index in dbHelper.objectStores[store].indices) {
newStore.createIndex(dbHelper.objectStores[store].indices[index].indexName,
dbHelper.objectStores[store].indices[index].indexName,
{unique : dbHelper.objectStores[store].indices[index].isUnique});
}
console.log(dbHelper.objectStores[store].name + ' created.');
}
};
request.onsuccess = function(e) {
console.log('DB ' + dbHelper.dbName + ' open.');
dbHelper.indexedDB.db = e.target.result;
onCompleteCallback();
};
request.onerror = onErrorCallback;
};
Here are some of the CRUD functions(the ones in question):
dbHelper.findItemWithIndex = function(keyValue, storename,
onCompleteCallback,onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var index = store.index(keyValue.key);
index.get(keyValue.value).onsuccess = function(event) {
onCompleteCallback(event.target.result);
};
};
dbHelper.addItemToStore = function(item, storename,
onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.add(item);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
dbHelper.deleteItemFromStore = function(itemId, storename,
onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.delete(itemId);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
dbHelper.updateItem = function(item, storename, onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.put(item);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
Finally, the code from the controller where the transactions are invoked.
The strategy here, is that the item is added to the db using the addItemToStore function the first time it is persisted, and then afterwards the updateItem function.
After adding the first time, the object is immediately fetched in order to keep working on it with the assigned id from the db.
$scope.updateTemplate = function() {
console.log('Saving..');
var onCompleteCallback = {};
if(!$scope.formTemplate.firstSave) {
onCompleteCallback = $scope.updateModel;
} else {
$scope.formTemplate.firstSave = false;
onCompleteCallback = $scope.setId;
}
$db.updateItem($scope.formTemplate, $scope.objectStore.name,
onCompleteCallback, $scope.dbError);
};
$scope.newItem = function() {
$db.addItemToStore($scope.formTemplate, $scope.objectStore.name,
$scope.setId, $scope.dbError);
};
$scope.setId = function() {
$db.findItemWithIndex(
{key: 'title',
value: $scope.formTemplate.title},
$scope.objectStore.name,
function(result) {
console.log(JSON.stringify(result));
$scope.formTemplate = result;
},
function(error) {
$scope.dbError(error);
});
}
It's here everything goes to hell.
I add an object, go back to another view and find it in the list with id=1.
I add another object, go back to the list view, and there it is with id=2.
And so forth and so forth..
Then, after updating either of the objects with the $scope.updateTemplate function, which also works like a charm, things get interesting:
The next object added gets id=1 and totally erases good old numero uno from earlier.
The next objects also get id's that cause them to replace the already existing objects.
What could cause this?
For testing I'm using Safari 8 in OS 10.10 and I'm deploying to an LGG2 with KitKat 4.4.2.
To be honest, I skimmed, but I saw this, "Safari 8" - the latest iOS and Safari have serious bugs with IndexedDB: http://www.raymondcamden.com/2014/9/25/IndexedDB-on-iOS-8--Broken-Bad
In iOS9, many of the IndexedDb bugs are fixed, but not all. We are currently testing on iOS9 Beta 2 and this particular bug that you found is not fixed.
We were able to work around this problem by not using autoincrement on our object stores. We just manually find the max key value and increment that.
Inserting an object looks something like this:
var store = db.transaction([entity], "readwrite").objectStore(entity);
store.openCursor(null, "prev").onsuccess = function (event) {
var maxKey = event.target.result.key || 0;
object.id = maxKey + 1;
store.add(object);
}