How to do backward pagination in dynamoDB with LastEvaluatedKey? - javascript

param.FilterExpression = "#black_listed = :black_listed_val";
param.Limit = 5
param.ExpressionAttributeValues = {":black_listed_val": body.blacklisted};
param.ExpressionAttributeNames = {"#black_listed": "black_listed"}
param.ScanIndexForward = true
param.ExclusiveStartKey = {"id": "11931258-b582-4d2d-98d9-aa8ae0fe2e43"}
I can do forward pagination with this code, but how could I go back?

To page backward you need to set ScanIndexForward to false AND the ExclusiveStartKey to the key of the first item of the second page. As an example, say your first page is items 1, 2 & 3. The response from that will include a LastEvaluatedKey for 3. You can use that to go forward by passing that to the ExclusiveStartKey, resulting in 4, 5 & 6. Going backward you can't do that, because using that same key would result in just 2 & 1. Instead you need to use the key of 4 as your ExclusiveStartKey.

Change
param.ScanIndexForward = true
to
param.ScanIndexForward = false

Related

How to push a boolean into an array? "undefined" error

Why does the console print "undefined" when I print index 3? I'm trying to set index 3 to false and after 7 secs set it to true.
I've tried to change "nr", index 2, with success trying to narrow down the problem.
if (Math.random() < 0.005) {
nx = Math.random()*1000; //index0
ny = 200; //index1
nr = 5;//index2
var nfall = false; //index3
Apples.push([nx,ny,nr,nfall]); //simply inserting 'false' into index 3 doesn't work either.
setTimeout(function(){ Apples[2][2] = 500; Apples[2][3] = true;}, 7000); //3rd apple
console.log("New circle, x:"+Apples[2][0]+" y:"+Apples[2][1]+" nr:"+Apples[2][2] +" nfall:"+Apples[2[3]]);
//What works - in 7 seconds "nr" is updated from 5 to 500, but nfall is still undefined and NOT = true
Initially I expect the output of false from index 3 "nfall" then I expect the output of true from index 3 "nfall" after 7 secs.
Thank you
In your console.log call, you're accessing the array like this:
Apples[2[3]]
But it should be
Apples[2][3]
In the first version, you're accessing index 3 of the number 2 which actually is not an error, just undefined.
Your issue is the last part - you're accessing Apples[2[3]] which doesn't exist, and it's invalid syntax. You want to get the third item in Apples (which is an array), then access the fourth item of that array - do it simply with `Apples[2][3]:
const Apples = [1, 2, [3, 4, 5, 6]];
console.log(Apples[2][3]);

what is the equivalent of a reduce in javascript

I'm a backend dev moved recently onto js side. I was going through a tutorial and came across the below piece of code.
clickCreate: function(component, event, helper) {
var validExpense = component.find('expenseform').reduce(function (validSoFar, inputCmp) {
// Displays error messages for invalid fields
inputCmp.showHelpMessageIfInvalid();
return validSoFar && inputCmp.get('v.validity').valid;
}, true);
// If we pass error checking, do some real work
if(validExpense){
// Create the new expense
var newExpense = component.get("v.newExpense");
console.log("Create expense: " + JSON.stringify(newExpense));
helper.createExpense(component, newExpense);
}
}
Here I tried to understand a lot on what's happening, there is something called reduce and another thing named validSoFar. I'm unable to understand what's happening under the hood. :-(
I do get the regular loops stuff as done in Java.
Can someone please shower some light on what's happening here. I should be using this a lot in my regular work.
Thanks
The reduce function here is iterating through each input component of the expense form and incrementally mapping to a boolean. If you have say three inputs each with a true validity, the reduce function would return:
true && true where the first true is the initial value passed into reduce.
true && true and where the first true here is the result of the previous result.
true && true
At the end of the reduction, you're left with a single boolean representing the validity of the entire, where by that if just a single input component's validity is false, the entire reduction will amount to false. This is because validSoFar keeps track of the overall validity and is mutated by returning the compound of the whether the form is valid so far and the validity of the current input in iteration.
This is a reasonable equivalent:
var validExpense = true;
var inputCmps = component.find('expenseform')
for (var i = 0; i < inputCmps.length; i++) {
// Displays error messages for invalid fields
inputCmp.showHelpMessageIfInvalid();
if (!inputCmp.get('v.validity').valid) {
validExpense = false;
}
}
// Now we can use validExpense
This is a somewhat strange use of reduce, to be honest, because it does more than simply reducing a list to a single value. It also produces side effects (presumably) in the call to showHelpMessageIfInvalid().
The idea of reduce is simple. Given a list of values that you want to fold down one at a time into a single value (of the same or any other type), you supply a function that takes the current folded value and the next list value and returns a new folded value, and you supply an initial folded value, and reduce combines them by calling the function with each successive list value and the current folded value.
So, for instance,
var items = [
{name: 'foo', price: 7, quantity: 3},
{name: 'bar', price: 5, quantity: 5},
{name: 'baz', price: 19, quantity: 1}
]
const totalPrice = items.reduce(
(total, item) => total + item.price * item.quantity, // folding function
0 // initial value
); //=> 65
It does not make sense to use reduce there and have side effects in the reduce. Better use Array.prototype.filter to get all invalid expense items.
Then use Array.prototype.forEach to produce side effect(s) for each invalid item. You can then check the length of invalid expense items array to see it your input was valid:
function(component, event, helper) {
var invalidExpenses = component.find('expenseform').filter(
function(ex){
//return not valid (!valid)
return !ex.get('v.validity').valid
}
);
invalidExpenses.forEach(
//use forEach if you need a side effect for each thing
function(ex){
ex.showHelpMessageIfInvalid();
}
);
// If we pass error checking, do some real work
if(invalidExpenses.length===0){//no invalid expense items
// Create the new expense
var newExpense = component.get("v.newExpense");
console.log("Create expense: " + JSON.stringify(newExpense));
helper.createExpense(component, newExpense);
}
}
The mdn documentation for Array.prototype.reduce has a good description and examples on how to use it.
It should take an array of things and return one other thing (can be different type of thing). But you won't find any examples there where side effects are initiated in the reducer function.

I'm trying to use jquery to create a div containing columns but I can't get my array to format correctly

I have an array that contains dates. and for some reason I can't get it to show on my screen I've been debugging for a few days now and I've tracked it down to a single line, but the line has worked before and I can't figure out what the issue might be.
The array looks like this:
var selectItems =
[ "05-26-2017", "06-02-2017", "06-09-2017",
"06-16-2017", "06-23-2017", "06-30-2017", "07-07-2017", "07-14-2017",
"07-21-2017", "07-28-2017"...];
It's passed as an argument from another function, but that's how it's showing in console.log().
I might be going about this the wrong way, maybe even a lot further around then I need to but this is what I've come up with:
1. function setTHead(selectItems) {
2 var formatString;
3. for (var x = 0; x < 12; x++) {
4. formatString = selectItems[x].replace(/[^0-9/-]/g, "").toString();
5. console.log(selectItems);
6. $('#datTab').append("<div id='col" + x + "' class='column'>'" + formatString + "'</div>");
7. }
8. }
the array up top is what's showing from the console.log 5 lines down.
the sixth line is what is seeming to give me issues. Nothing is put on the page at all.
I'm getting a console error saying:
jQuery.Deferred exception: selectItems is undefined setTHead#http://localhost/mySite/script.js:136:9
startUp2#http://localhost/mySite/script.js:146:5
#http://localhost/mySite/table.php:19:9
mightThrow#http://localhost/mySite/lib/jquery.js:3586:52
resolve/</process<#http://localhost/mySite/lib/jquery.js:3654:49
setTimeout handler*resolve/<#http://localhost/mySite/lib/jquery.js:3692:37
fire#http://localhost/mySite/lib/jquery.js:3320:30
fireWith#http://localhost/mySite/lib/jquery.js:3450:29
fire#http://localhost/mySite/lib/jquery.js:3458:21
fire#http://localhost/mySite/lib/jquery.js:3320:30
fireWith#http://localhost/mySite/lib/jquery.js:3450:29
ready#http://localhost/mySite/lib/jquery.js:3923:13
completed#http://localhost/mySite/lib/jquery.js:3933:9
EventListener.handleEvent*#http://localhost/mySite/lib/jquery.js:3949:9
#http://localhost/mySite/lib/jquery.js:39:9
#http://localhost/mySite/lib/jquery.js:17:3
undefined
followed by:
TypeError: selectItems is undefined
and thats pointing to line 6.
if anyone has any advice I would be very much appreciative. Thank you in advance.
EDIT: A little more code:
function startTblView(defSel) {
if (defSel === true) {
setCookie('defSel', true, 7);
} else{
setCookie('defSel', false, 7);
}
saveSelected();
window.open('table.php', '_self');
defSel = getCookie('defSel');
if (defSel) {
selectItems = getDefDates();
}else {
selectItems = reGetSelected();
}
setTHead(selectItems);
}
defSel, is a boolean passed from my last page stating whether I'm doing a default view or a custom view, the custom view is passed from saveSelected();
saveSelected is a function for just saving the selected global value as a cookie so I can pull it out on the next page.
getDefDates pulls the default values for the array
reGetSelected, gets the selected array from the cookie.
I apologize for wonky naming conventions. I'm the only one working on this site and I'm just making sure the names don't overlap.
You can do this :
HTML code
<div id="datTab"></div>
JS code
var selectItems =
[ "05-26-2017", "06-02-2017", "06-09-2017",
"06-16-2017", "06-23-2017", "06-30-2017", "07-07-2017", "07-14-2017",
"07-21-2017", "07-28-2017"];
function setTHead(selectItems) {
var formatString;
$.each( selectItems, function( index, value ){
formatString = value.replace(/[^0-9/-]/g, "").toString();
$('#datTab').append("<div id='col" + index + "' class='column'>'" + value + "'</div>");
});
};
You can use $.each, its better than 'for' with javascript.
The .each() method is designed to make DOM looping constructs concise
and less error-prone. When called it iterates over the DOM elements
that are part of the jQuery object. Each time the callback runs, it is
passed the current loop iteration, beginning from 0. More importantly,
the callback is fired in the context of the current DOM element, so
the keyword this refers to the element.
I did a JsFiddle
Here.

Deleting a node in the center of a single linked list. What happens to the node?

I have a quick question regarding the deletion of a node in the center of a linked list given that you only have access to that node. I've taken a look at the solution and while I understand what is happening, I am confused as to what actually happens to the node. For instance, if I have the nodes with values 1, 2, 3, 4, 5 in my linked list, why am I left with 1, 2, 4, 5 instead of 1, 2, 4, 4, 5?
Thanks in advance for any help.
SinglyList.prototype.deleteMiddle = function(value) {
var current = this.head;
while (current.value !== value) {
current = current.next;
}
if (current.next) {
current.value = current.next.value;
current.next = current.next.next;
} else {
current = null;
}
}
So you have linked list with nodes 1, 2, 3, 4 and 5, from which node 3 is removed. The removal of node 3 is actually a redirecting of some links. In this case, node 2 will not link to node 3 as its next node anymore, but it will link to node 4 as its next node instead. In case of a doubly linked list, this is also true the other way around, e.g. node 4 will link back to node 2 instead of node 3.
So, node 3 will not actually be removed physically, but any references to node 3 will be removed, which means logically it does not exist anymore. At some point in time, a garbage collector will remove node 3 physically because there are no more references pointing to that node.
Basically, you need another variable for the last node.
If not at the start, then combine the previous next pointer to the actual next pointer:
lastNode.next = node.next;
Working model:
function Node(value) {
this.value = value;
this.next = undefined;
}
function setValues(a) {
var n = new Node(a.shift());
if (a.length) {
n.next = setValues(a);
}
return n;
}
function deleteNode(list, value) {
var node = list,
lastNode;
while (node.value !== value) { // find value
lastNode = node;
node = node.next;
}
if (lastNode) { // inside the list
lastNode.next = node.next;
} else { // at the start
list.value = node.next.value;
list.next = node.next.next;
}
}
var list1 = setValues([1, 2, 3, 4, 5]);
document.write('<pre>' + JSON.stringify(list1, 0, 4) + '</pre>');
deleteNode(list1, 3);
document.write('<pre>' + JSON.stringify(list1, 0, 4) + '</pre>');
I'm not sure how this relates to JavaScript but you can think of a Linked List as a series of nodes:
1 -> 2 -> 3 -> 4 -> 5
Each node has a pointer to the next node. When you remove 3, the pointer from on 2 to 3 is updated to point to what 3 pointed to (4). So you end up with:
1 -> 2 -> 4 -> 5
If you are asking how do you delete it if you can't go backwards to see that 2 is pointing to 3, well think about how you traverse a linked list -- there is only one way to go. So an algorithm to remove a node is going to have to keep a pointer to the prior, current and next node. That way, when the current node is remove (3), it can look at the prior (2) and the next (4). Of course 3 already has a reference to 4 so the next pointer isn't needed.
There's more than one linked list implementation out there. But if we're talking abstract: if you remove one element in a linked list, it becomes two linked lists. one ending before the removed element, the second one beginning after the removed element.
What happens to the node ist what you actually mean by "deleting". There is no "emtpy" space in the linked list where the removed node once was. It was removed, as requested. Depending on the implementation of the remove operation the lose ends of the two resulting lists can be combined, to form a (one!) new linked list, with 1,2,4,5. Or they are not, then you end up with described 2 lists. The end of list 1 points to nil / null / somwhere, the reference to the beginning of the other list is lost, unless you saved it somewhere.
So you end up with either 1->2->4->5 or 1->2-> + 4->5

Next/Previous navigation of an Observable

I have an observable of blog posts, converted from an array:
let posts = Rx.Observable.fromArray(blogPosts)
And two observables nextClicks and prevClicks of button click events for next/previous navigate respectively:
What I want is:
Initially the posts observable emits the very first post and
then wait for click events
posts emits next post when nextClicks emits (repeat current post
if no next available)
posts emits prev post when prevClicks emits (repeat current post
if no prev available)
And I'm not sure if this is possible:
Two observables postNextable and postPrevable, derived from
posts, indicating whether there is a next/prev post available in
posts respectively
Thanks in advance!
There are several ways to do 1, 2, 3 and 4. For number 4, I wonder how you plan to use those observables.
One way which only uses pure functions and no subjects is :
var blogPosts$ = Rx.Observable.just(blogPosts);
var index$ = Rx.Observable.merge(nextClicks, prevClicks)
.withLatestFrom(blogPosts$, function(ev, blogPosts){return {posts: blogPosts, ev : ev};})
.scan(function(index, posts_and_ev){
return isNextClick(posts_and_ev.ev) && isNextable(posts_and_ev.posts, index) ? index + 1
:isPrevClick(posts_and_ev.ev) && isPrevable(posts_and_ev.posts, index) ? index - 1
:index
}, 0);
var currentPost$ = index$.withLatestFrom(blogPosts$, function (index, blogPost){return blogPost[index]; }).startWith(blogPosts[0]);
var postNextable = index$.withLatestFrom(blogPosts$, function (index, blogPost){return isNextable(blogPost, index);});
var postPrevable = index$.withLatestFrom(blogPosts$, function (index, blogPost){return isNextable(blogPost, index);})
The output you seek is named here currentPost$.
Code test included thereafter. isNextable, isNextClick, isPrevable, isPrevClick have obvious semantics, and are easy to write (for example discriminating on key codes or button ids or else for your next and prev events). sample code

Categories

Resources