It states here that the following is a pure function:
function insert(DB, user) {
return function() {
throwIfUserExists(DB, user);
var savedUser = saveUser(DB, user);
return savedUser;
}
}
and that the following is an impure function:
function insert(user) {
if (DB.exists(user.id)) {
throw Error("users exists");
}
var id = DB.insert(user);
user.id = id;
return user;
}
I don't understand how the first function is pure, since it returns a function that produces side effects. Am I wrong and if not, how could the function be written to be pure?
A pure function is a function which:
Given the same input, will always return the same output.
Produces no side effects.
Now pay attention to the first point.
In your first example, as long as you keep sending in the same DB and user the output would be the same. The construction of savedUser or throwIfUserExists functions would affect the output of the first insert fn but the insert function in essence would be a pure function.
However, in the second function the output would be different for each call even though the user is the same. To be precise, the line user.id = id; is the one that is producing the "side effects".
Read Eric Elliot's article on pure functions : https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976
Related
output = true;
if($("#password-field").css('display') != 'none') {
if(!($("#verificationCode").val())) {
output = false;
$("#code-error").html("required");
}
var codeverify = function(){
var code = document.getElementById("verificationCode").value;
coderesult
.confirm(code)
.then( function(result) {
if (result.user.uid) {
let phoneNumber = result.user.phoneNumber;
//alert(output);
alert("Verification done");
console.log(phoneNumber);
} else {
alert(output);
$("#code-error").html("no user");
output = false;
}
})
.catch(function(error) {
output = false;
$("#code-error").html("wrong");
alert(error.message);
});
}();
}
return output;
When i run this code everything works fine. but before checking the codeverify function it return the output to true even if the codeverify() function returns false
PS. I am using wizard form.
This comes down to how you write JavaScript code, I found that usually when to get to a point where my procedures are out of sync it means that I have done something wrong in previous steps. This is usually only fixed by refactoring.
Remember JavaScript does not behave the same as other languages.
What I can see from your procedure is that you are trying to do many things in one go.
Although I do not have a solution I have a suggestion, consider each action that you want your procedure to execute. Declare a separate function for each of these steps, even if your function only has one line to execute.
If there are dependencies make sure they can be resolved by parameterization.
And lastly, think pure functions. Try and structure every function to receive something and return something.
Another tip that I can give is, write your procedure to select and hold elements in variables until they are required. Consider what elements are required in execution, which of those are in the dom when execution starts and set them to variables before you start executing, then during execution if elements are added that are maybe required for later select them immediately after they are placed in the dom, this means that as your procedure executes all the ingredients are available to do whatever must be done they don't have to go find what they need on the fly.
Good Luck and happy coding.
Your coderesult.confirm(code) using promise(then & catch) so i assume it is asynchronous. You need to google yourself to learn what is async
One important thing of JS behavior is JS always process the rest of the code if there is a async function in between.
Sample:
console.log(1)
setTimeout(()=>{
console.log(2,"i suppose at position 2 but i'm at the last. This is because setTimeout is async function")
},1000)
console.log(3)
In your case, your codeverify function has async code (.confirm()) in between, so JS will process the code after codeverify (return output)until codeverify is fully completed.
Since your output was set at true since the beginning, it will return true from the last row of code return output before your codeverify completed, this is why you always get true. If you change the first row output = undefined, i believe you will see undefined result.
To solve this, one of the way is you can wrap the entire codeverify as Promise.
function codeverify(){
return new Promise((resolve,reject)=>{
var code = document.getElementById("verificationCode").value;
coderesult.confirm(code).then( function(result) {
if (result.user.uid) {
let phoneNumber = result.user.phoneNumber;
//alert(output);
alert("Verification done");
console.log(phoneNumber);
output = true
resolve(output)
} else {
alert(output);
$("#code-error").html("no user");
output = false;
resolve(output)
}
}).catch(function(error) {
output = false;
$("#code-error").html("wrong");
alert(error.message);
reject(output) //you can reject(error.message) so you can pass error message back.
});
})
}
You can execute the function like this:
codeverify().then(successData=>{
console.log(successData) //from what you resolve
}).catch(failedData=>{
console.log(failedData) //from what you reject
})
Lastly, take some time to study what is Asynchronous and What Promise to do with Async because it is everywhere in JS.
I have a an async function that checks if the id already exists in a table.
async function generateIdentifier () {
try {
let exists;
let id;
do {
id = someRandomStringGenerator();
const email = await Database.find({id});
if (email.length > 0) {
exists = true;
} else {
exists = false;
}
} while (exists);
return id;
} catch (e) {
throw e;
}
}
With the code above, the find method will return an array. If the array is empty, means no id is found. When an id is found, it should generate a new one until id is unique.
Also, yes this works though performance wise, are there better options with doing things like this?
I suggest you to use callback function as below. I took an API call to represent your Database request and I put the condition to loop until the string has the character v inside. With that it will work like a charm.
function loadData(callback){
$.ajax({url: "https://helloacm.com/api/random/?n=10", success: function(response){
callback(response);
}});
}
function checkData(response){
if(response.includes("w")){
console.log(response, "good");
} else {
console.log(response, "bad");
loadData(checkData);
}
}
function register(){
loadData(checkData);
}
register();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Yes this works, the entire selling point of async await is that you can make promise based code look like regular imperative constructs (such as while loops) just by adding the await keyword whenever you call out to another async function.
Performance wise, you could obviously benefit from generating the random ID on the server so that you always get an ID which is known to be unique in a single call. This is probably not a problem in practice as having more than 1 collision is likely to be very rare if the space of IDs is sufficiently large.
infinity do while is good when you have multiple cases when you need to change the condition of loop. In your case its simple. If found record, return otherwise do it again. However, the function name should represent it function. In your case is register, but actually you retrieving random record. Performance? Well, you are not really saving much here. You have couple async calls which will blocks your script until resolved. Example without dowhile https://stackblitz.com/edit/js-bgyman
I know this is a highly answered topic, but reading tons of posts I can't figure if my dilema has a solution as I want.
I want to write a simple function that returns the User Name passing the UserId. It will be used everywhere to multiple purposes.
function getUserName(userId) {
//...some code to retrieve the Name from a REST webservice like $.ajax or $.getJSON or anything else that helps me achieve my need
return name;
}
$('#txtUserName').val(getUserName(sessionStorage.userId));
//...
if (getUserName(sessionStorage.userId) == getUserName($('#inputUser').val())) {
alert('Error: User typed with the same name as '+ sessionStorage.userID);
}
I know that can rewrite it all to put callback's or whatever, but I want to know if there's any implementation that makes possible to write this simple function that returns a value from a PHP webService.
I imagine a function like this:
function getUserName(userId) {
var users ={
'me': 'Seak Oink'
, 'you': 'Who knows'
, 'jd': 'John doe'
};
return users[userId];
}
...but instead of having the fixed users object, i retrieve it from my php webService that gets it from a DB.
Using a callback, makes impossible to handle values. For example (if I'd use callback and assuming calling getUserName(userId, callback) handles the function call):
$('#txtUserName').val('');
getUserName(sessionStorage.userId, function(userName) {
$('#txtUserName').val(userName);
});
if ($('#txtUserName').val() == '') {
alert('user '+ sessionStorage.userId +' doesn't exist');
}
Instead, you could answer me to put it into the callback, but if need to call again my function, I must nest it to a callback again and again... I think it's a bad programming practice:
$('#txtUserName').val('');
getUserName(sessionStorage.userId, function(userName) {
$('#txtUserName').val(userName);
getUserName($('#inputUser').val(), function (userName2) {
if (userName2 == userName) {
alert('Error: User typed with the same name as '+ sessionStorage.userID);
}
//....here I must continue the code flow instead of continuing to caller's flow.
//...nesting, and more nesting... impossible to read code?¿¿?:
userpermission(userId, function(bAllowed) {
if (bAllowed) {
saveRecord(userId, sKey, sSomeText, function () {
alert('record saved -or not-');
// ...and continue nesting
});
} else {
alert('forbidden');
}
});
});
});
... instead of this simple code flow logic:
var lOk = false;
$('#txtUserName').val('');
$('#txtUserName').val(getUserName(sessionStorage.userId);
if ($('#inputUser').val() == getUserName($('#inputUser').val())) {
alert('Error: User typed with the same name as '+ sessionStorage.userID);
}
if (userpermission(userId)) {
lOk = saveRecord(userId, sKey, sSomeText);
} else {
alert('forbidden');
}
if (lOk) {
alert('record saved');
}
// ...continue the validation process or whatever
I understand the simple example of retrieving a value with a callback, but don't using it in code logic.
I've been read How do I return the response from an asynchronous call? and much more like that and understood, but I can't uderstand how to use retrieved values from different sources and apply the necessary logic. Basicly, how to order the chaos?
Looks like you're experiencing callback hell.
That happens when you have several asynchronous functions and you need to handle all their errors and success.
That's exactly for that case that promises have been invented.
If you don't have ES6, have a look on jquery promises, otherwise they are built-in : ES6 promise
They allow more readable, synchronous like code.
For example, you can do code like that:
$.when( // waits for two promises to be resolved
getUserName(userId)
.then(function(name) { // once name resolved, fetch profile (new promise)
return getUserProfile(name);
}),
getUserPoints(userId) // another independent promise
).done(function(userProfile, userPoints) { // the two above are done, I can move on and update the DOM
$("#profile").doSomething(userProfile);
$("#points").doOtherThing(userPoints);
});
I'm used to throwing an instance of some error class and having them be caught somewhere down the line in the app, to account for user error.
An example might be validating the username:
function validateUsername (username) {
if (!/^[a-z0-9_-]{3,15}$/.test(username)) {
throw new ValidationError('Please enter 3-15 letters, digits, -, and/or _.');
}
}
$('#username').blur(function () {
try {
validateUsername($(this).val());
} catch (x) {
$('<p></p>').addClass('error').text(x).insertAfter(this);
}
});
But now I'm realizing that I can't use these same practices for asynchronous calls. For example:
function checkUsernameAvailability (username) {
$.get('/users/' + username).done(function () {
// Done = user returned; therefore, username is unavailable
// But I can't catch this error without resorting to something gross
// like window.onerror
throw new ValidationError('The username you entered is already in use.');
});
}
I could make checkUsernameAvailability accept a callback and/or return a promise and have it execute said callback with the availability of the username.
$('#username').blur(function () {
checkUsernameAvailability(username, function (available) {
!available && alert('The username you entered is already in use.');
});
});
But part of what makes exceptions so powerful is that they can bubble up the stack until they get caught, whereas if I had another function that called another function that called checkUsernameAvailability, I'd need to pass the result of this callback manually all the way until I get to the place where I want to handle it.
What are some of the alternative methods for passing errors up the stack? I can think of some of these, but none of them are as clean as native exceptions:
Passing a flag, or the ValidationError instance, to a callback (Node.js approach could work too, passing an error or null as the first argument, and the data as the second); but then, if I don't want to handle it at that point in the stack, I need to pass the error up manually
Or passing 2 callbacks to the checkUsernameAvailability function, a success callback and an error callback; this seems to have the same drawbacks as the previous point
Triggering a "ValidationError" event so I can listen anywhere, but make sure to return false; in the handler so it doesn't execute higher in the stack; however, this pollutes the event namespace and could make it unclear as to which event listener will be executed first; plus, it's difficult to trace an event to its origin using the console
in principal it is like this
function Exception (errcode) {
this.code = errcode;
}
...
try {
...
throw new Exception('alpha');
...
} catch (e) {
if (e.code === {something}) {
}
}
If it helps, I recently took the first release of the Rogue game written for UNIX in C and rewrote it for javascript to work in a browser. I used a technic called continuation to be able to wait for key entry by the user because in javascript the are no interrupts.
So I would have a piece of code like this:
void function f() {
// ... first part
ch = getchar();
// ... second part
}
that would be transformed in
function f() {
// ... first part
var ch = getchar(f_cont1);
return;
// the execution stops here
function f_cont1 () {
// ... second part
}
}
the continuation is then stored to be reuse on a keypressed event. With closures everything would be restarted where it stoped.
I'm using Node.js + Express + nodejs-sqlite3 to make a form that when submited will insert a new row on an slite3 database.
On query sucess I want to write certain response.
So the small big problem is just: Modify a string that will be storing the html to be shown, inside the callback function of sqlite3.run()
I read about closures, and passing an object with methods to modify its own attributes. But it seems it's not working. It will pass the object attributes and methods, but no change will remain when the callback function ends. I read that objects will be passed as reference, not copies.
This is the code:
app.post("/insert.html", function(req, res){
function TheBody(){
this.html = "";
this.msg = "";
this.num = "";
}
TheBody.prototype.add = function(string){
this.html = this.html + string;
}
var body = new TheBody();
body.msg = req.body.message;
body.num = req.body.number;
var insertCallback = function(data){
return function(err){
if( err != null){
console.log("Can't insert new msg: " + err.message);
data.add("ERROR-DB");
} else {
console.log("Ok. Inserted: " + data.msg);
console.log(data.html);
data.add("OK - MSG: "+data.msg+" NUM: "+data.num);
console.log(data.html);
}
};
};
var db = new lite.Database('database.db');
var query = "INSERT INTO outbox (message, number) VALUES (?, ?)";
db.run(query, [body.msg, body.num], insertCallback(body) );
res.setHeader('Content-Type', 'text/html');
res.setHeader('Content-Length', body.html.length);
res.end(body.html);
}
On server side I'll see
Ok. Inserted: TestString
[Blank space since data.html still has no information]
OK - MSG: TestString NUM: TestNumber [Showing that indeed was modified inside the function]
But on the client side res.end(body.html); will send an empty string.
The object is not being passed as reference.
What's missing in the code, and what simpler alternatives I have to change a string variable inside a callback anonymous function?.
I already know I could use response.write() to write directly on the function if it were more simpler. But I discovered it would only work if I use response.end() inside the callback, otherwise (being outside as it is now) it will meet a race condition where the buffer will be closed before sqlite3.run() be able to use response.write().
-------- Answered --------
As hinted by Justin Bicknell and confirmed by George P. Nodejs-sqlite3 functions are run asynchronously. So I was ending the stream to the client before the callback would be called, thus nothing was being printed.
This was a problem more about "This is SPART- nodejs, so write your stuff according to events'" rather than a logic one. I found this kind of programming kind of convoluted but nobody else than me told me to use nodejs. For those wondering about how one could put some order over the order of queries on the database, nodejs-sqlite3 functions returns a database object that is used to chain the next query.
Since I was printing the information to the client just once in every handled event, the resulting object ended like this:
function TheBody(response){
this.response = response;
}
TheBody.prototype.printAll = function(string){
this.response.setHeader('Content-Type', 'text/html');
this.response.setHeader('Content-Length', string.length);
this.response.end(string);
}
Preferring that to clutter all the code a lot of res.setHeader() lines.
node-sqlite3 methods are, by default, run in parallel (asynchronously). That means that your code is going through this timeline:
Your code calls db.run(...)
Your code calls res.end(...)
db.run completes and calls your callback.
This is the source of a huge number of questions here on SO, so you can almost certainly find a better answer than anything that I could write here in a reasonable amount of time.
I would start here: How does Asynchronous Javascript Execution happen? and when not to use return statement?