Resetting a Bacon property on value changed to empty - bacon.js

TL;DR
How can I reset emailProfile/aliasProfile when email/alias is cleared after having a value?
Slightly longer version
I have a form that has inputs for email and alias. Neither is mandatory. But, if you fill in the alias field, it might require the email as well, if the alias is reserved.
So far so good, I have the pipe setup from an empty form, up until checking if an alias is reserved and whether the given email matches up. This works correctly and reliably.
Where my setup falters, is when after filling in a correct e-mail I clear the email. The status of emailProfile remains status quo (last server response).
What I want to achieve, is to clear emailProfile when email has no value (or actually when validEmail is false), but in all other cases return the last server response.
The direct (and only) way to tackle the problem I can think of, would be to drop the filter and return null from the lookup function when validation fails, but there has to be a better way, right?
// Functions that can be assumed to work as they should (they do):
// form.findInput, validAlias,validEmail, compose,
// fetchProfilesByAlias, fetchProfileByEmail
var alias = Bacon.fromEventTarget(form.findInput("alias"), "change").
merge(
Bacon.fromEventTarget(form.findInput("alias"), "keyup")
).
map(".target").
map(".value").
skipDuplicates().
toProperty(form.findInput("alias").value);
var email = Bacon.fromEventTarget(form.findInput("email"), "change").
merge(
Bacon.fromEventTarget(form.findInput("email"), "keyup")
).
map(".target").
map(".value").
skipDuplicates().
toProperty(form.findInput("email").value);
var aliasProfiles = alias.
debounce(600).
filter(validAlias).
flatMapLatest(compose(Bacon.fromPromise.bind(Bacon), fetchProfilesByAlias)).
toProperty(null);
var emailProfile = email.
debounce(600).
filter(validEmail).
flatMapLatest(compose(Bacon.fromPromise.bind(Bacon), fetchProfileByEmail)).
toProperty(null);

This is the most straightforward way I can think of.
var emailProfile = email.
debounce(600).
flatMapLatest(function(email) {
if (validEmail(email)) {
return Bacon.fromPromise(fetchProfileByEmail(email))
} else {
return null
}
}).
toProperty(null)
Pretty much the same that you already discovered, except the if is not in the lookup function :)

Related

Does gorm interpret the content of a struct with a logical OR?

New to SQL, I am writing as an exercise an API middleware that checks if the information contained in some headers match a database entry ("token-based authentication"). Database access is based on GORM.
To this, I have defined my ORM as follows:
type User struct {
ID uint
UserName string
Token string
}
In my middleware I retrieve the content of relevant headers and end up with the variables userHeader and tokenHeader. They are supposed to be matched to the database in order to do the authentication.
The user table has one single entry:
select * from users
// 1,admin,admintoken
The authentication code is
var auth User
res := db.Where(&User{UserName: userHeader, Token: tokenHeader}).Find(&auth)
if res.RowsAffected == 1 {
// authentication succeeded
}
When testing this, I end up with the following two incorrect results (other combinations are correct):
with only one header set to a correct value (and the other one not present) the authentication is successful (adding the other header with an incorrect value is OK (=auth fails))
no headers set → authentication goes though
I expected my query to mean (in the context of the incorrect results above)
select * from users where users.user_name = 'admin' and users.token = ''
select * from users where users.user_name = '' and users.token = ''
and this query is correct on the console, i.e. produces zero results (ran against the database).
The ORM one, however, seems to discard non-existing headers and assume they are fine (this is at least my understanding)
I also tried to chain the Where clauses via
db.Where(&User{UserName: userHeader}).Where(&User{Token: tokenHeader}).Find(&auth)
but the result is the same.
What should be the correct query?
The gorm.io documentation says the following on the use of structs in Where conditionals:
When querying with struct, GORM will only query with non-zero fields,
that means if your field’s value is 0, '', false or other zero
values, it won’t be used to build query conditions ...
The suggested solution to this is:
To include zero values in the query conditions, you can use a map,
which will include all key-values as query conditions ...
So, when the token header or both headers are empty, but you still want to include them in the WHERE clause of the generated query, you need to use a map instead of the struct as the argument to the Where method.
db.Where(map[string]interface{}{"user_name": userHeader, "token": tokenHeader}).Find(&auth)
You can use Debug() to check for the generated SQL (it gets printed into stderr); use it if you are unsure what SQL your code generates

Terraform: How Do I Setup a Resource Based on Configuration

So here is what I want as a module in Pseudo Code:
IF UseCustom, Create AWS Launch Config With One Custom EBS Device and One Generic EBS Device
ELSE Create AWS Launch Config With One Generic EBS Device
I am aware that I can use the 'count' function within a resource to decide whether it is created or not... So I currently have:
resource aws_launch_configuration "basic_launch_config" {
count = var.boolean ? 0 : 1
blah
}
resource aws_launch_configuration "custom_launch_config" {
count = var.boolean ? 1 : 0
blah
blah
}
Which is great, now it creates the right Launch configuration based on my 'boolean' variable... But in order to then create the AutoScalingGroup using that Launch Configuration, I need the Launch Configuration Name. I know what you're thinking, just output it and grab it, you moron! Well of course I'm outputting it:
output "name" {
description = "The Name of the Default Launch Configuration"
value = aws_launch_configuration.basic_launch_config.*.name
}
output "name" {
description = "The Name of the Custom Launch Configuration"
value = aws_launch_configuration.custom_launch_config.*.name
}
But how the heck do I know from the higher area that I'm calling the module that creates the Launch Configuration and Then the Auto Scaling Group which output to use for passing into the ASG???
Is there a different way to grab the value I want that I'm overlooking? I'm new to Terraform and the whole no real conditional thing is really throwing me for a loop.
Terraform: How to conditionally assign an EBS volume to an ECS Cluster
This seemed to be the cleanest way I could find, using a ternary operator:
output "name {
description = "The Name of the Launch Configuration"
value = "${(var.booleanVar) == 0 ? aws_launch_configuration.default_launch_config.*.name : aws_launch_configuration.custom_launch_config.*.name}
}
Let me know if there is a better way!
You can use the same variable you used to decide which resource to enable to select the appropriate result:
output "name" {
value = var.boolean ? aws_launch_configuration.custom_launch_config[0].name : aws_launch_configuration.basic_launch_config[0].name
}
Another option, which is a little more terse but arguably also a little less clear to a future reader, is to exploit the fact that you will always have one list of zero elements and one list with one elements, like this:
output "name" {
value = concat(
aws_launch_configuration.basic_launch_config[*].name,
aws_launch_configuration.custom_launch_config[*].name,
)[0]
}
Concatenating these two lists will always produce a single-item list due to how the count expressions are written, and so we can use [0] to take that single item and return it.

How to check if a Gun unordered list is empty?

Given the following, how would one go about determining if the machines list is empty in order to add a machine?
let gun = new Gun();
let machines = gun.get('machines');
How do I check if the machines list is empty?
This from Mark Nadal:
// machineId and location defined elsewhere
machines.val(table => {
if (Gun.obj.empty(table, '_') {
// table is empty so we can add something to it
let machine = gun.get('machine/' + machineId);
machine.put({machineId, location}};
machines.set(machine);
} else {
// table is not empty
})
table is a data node that has all the row pointers in it (not the actual sub-objects)
so if table has 0 items on it, then it is empty! Or if table is null or undefined
HOWEVER, gun has its {_: {...}} meta data it includes on every node, so you need to ignore that.
Gun.obj.empty({}) tests if an object is empty (you can use lodash or something else), the second parameter tells it to IGNORE a key, like in this case '_'. So it will still say that yes it is empty if it has 0 properties other than the metadata property.

passing msqli to a function - can't suss out why it's not working

I've searched high and low for an answer on this, but I'm either missing something, or I just can't find anything in this context.
Background - trying to avoid spaghetti frenzy with a little casual project I'm starting; part of this will involve mainly just calls to a mysql database, displaying table content and so on. Simply put, like a CRM I guess.
I may be way off base here, but I want to be able to create my sql calls as functions, which will help if/when I tweak and tune, as well as creating a cleaner code for what I'm looking to do.
So, without further ado, I have this as a demomstration:
echo "<table>";
selectall('actions','content',$mysqli);
echo "</table><br><br>";
What this does is show all rows from my table of 'actions. "content" is just an example field name I'm passing through that I want to display, as it is the main human-relevant field name in that table. I'm also passing $mysqli through here for my function db call.
My function looks like this:
function selectall($s_table,$s_content,$mysqli){
$query = "SELECT * FROM " . $s_table;
$resource = $mysqli->query($query);
if ( !$resource ) throw new Exception($db->error);
while ( $row = $resource->fetch_assoc() ) {
$id = $row['id'];
echo "<tr><td>{$row[$s_content]}</td></tr>";
}
$resource->free();
$mysqli->close();
}
However.... it doesn't work, and it seems to throw a wobbly saying:
Warning: mysqli::query(): Couldn't fetch mysqli
This points to the action within the line $resource = $mysqli->query($query);
I know the function and everything is ok, as if I restate and declare $mysqli within the first line of the function, like so...
$mysqli = new mysqli(username password and so on in here);
... it works spot on.
$mysqli exists and works within the same code that is passing the variable within the function too.
This is early stages, so by shuffling the code around trying to poke the $mysqli pass into life I have perhaps made the code a little messier that intended, so try not to worry too much about that.
Anyone any ideas why it doesn't like this?
D'oh...
I had a
$mysqli->close();
in the lines above. Solved myself.
For reference, this is my function:
function selectall($s_table,$s_field,$mysqli){
if ($mysqli->connect_error) {die('Connect Error (' . $mysqli->connect_errno . ') '. $mysqli->connect_error);}
$s_table = preg_replace('/[^0-9a-zA-Z_]/', '', $s_table); // Cleans up the table name variable
$s_field = preg_replace('/[^0-9a-zA-Z_]/', '', $s_field); // Cleans up the field name variable
$query = "SELECT * FROM " . $s_table; // Adds passed table name to the select all
$resource = $mysqli->query($query);
if ( !$resource ) throw new Exception($db->error);
while ( $row = $resource->fetch_assoc() ) {
echo "<tr><td>{$row[$s_field]}</td></tr>"; // Content for each row of the select all
}
$resource->free();
$mysqli->close();
}
As you can see, I've also tried to protect the variables that enter the function.
This can be called via:
selectall('actions','content',$mysqli);
In this context, I want to view all the entries in the 'actions' table by the field name 'content'. This function, with some code above and below for a table, will create a new row for each entry.
I'll probably evolve a few, already created on that includes a delete button at the end of the line which is 'selectalldel'.
Open to comments on whether this actually is worthwhile, but thought I'd post up my corrected stupidity in case anyone finds this useful.

Check if an existing value is in a database

I was wondering how I would go about checking to see if a table contains a value in a certain column.
I need to check if the column 'e-mail' contains an e-mail someone is trying to register with, and if something exists, do nothing, however, if nothing exists, insert the data into the database.
All I need to do is check if the e-mail column contains the value the user is registering with.
I'm using the RedBeanPHP ORM, I can do this without using it but I need to use that for program guidelines.
I've tried finding them but if they don't exist it returns an error within the redbean PHP file. Here's the error:Fatal error: Call to a member function find() on a non-object in /home/aeterna/www/user/rb.php on line 2433
Here's the code that I'm using when trying this:
function searchDatabase($email) {
return R::findOne('users', 'email LIKE "' . $email . '"');
}
My approach on the function would be
function searchDatabase($email) {
$data = array('email' => $email);
$user = R::findOne('users', 'email LIKE :email, $data);
if (!empty($user)) {
// do stuff here
} // end if
} // end function
It's a bit more clean and in your function
Seems like you are not connected to a database.
Have you done R::setup() before R::find()?
RedBeanPHP raises this error if it can't find the R::$redbean instance, the facade static functions just route calls to the $redbean object (to hide all object oriented fuzzyness for people who dont like that sort of thing).
However you need to bootstrap the facade using R::setup(). Normally you can start using RB with just two lines:
require('rb.php'); //cant make this any simpler :(
R::setup(); //this could be done in rb.php but people would not like that ;)
//and then go...
R::find( ... );
I recommend to check whether the $redbean object is available or whether for some reason the code flow has skipped the R::setup() boostrap method.
Edited to account for your updated question:
According to the error message, the error is happening inside the function find() in rb.php on line 2433. I'm guessing that rb.php is the RedBean package.
Make sure you've included rb.php in your script and set up your database, according to the instructions in the RedBean Manual.
As a starting point, look at what it's trying to do on line 2433 in rb.php. It appears to be calling a method on an invalid object. Figure out where that object is being created and why it's invalid. Maybe the find function was supplied with bad parameters.
Feel free to update your question by pasting the entirety of the find() function in rb.php and please indicate which line is 2433. If the function is too lengthy, you can paste it on a site like pastebin.com and link to it from here.
Your error sounds like you haven't done R::setup() yet.
My approach to performing the check you want would be something like this:
$count = count(R::find('users', 'email LIKE :email', array(':email' => $email)));
if($count === 0)
{
$user = R::dispense('users');
$user->name = $name;
$user->email = $email;
$user->dob = $dob;
R::store($user);
}
I don't know if it is this basic or not, but with SQL (using PHP for variables), a query could look like
$lookup = 'customerID';
$result = mysql_fetch_array(mysql_query("SELECT columnName IN tableName WHERE id='".$lookup."' LIMIT 1"));
$exists = is_null($result['columnName'])?false:true;
If you're just trying to find a single value in a database, you should always limit your result to 1, that way, if it is found in the first record, your query will stop.
Hope this helps