Fundamental misunderstanding of how Angular handles a snippet? - javascript

I'm having a problem debugging some code in an Angular controller. This function is called when a form is submitted on our checkout page. I'm fairly new to Angular, and I'm a bit confused as to what is going on in this function.
$scope.handleStripe = function(status, response){
PayStripe.processPayment(status, response).then(
function(successMessage){
alert('success', successMessage);
Order.recordOrder(Cart.cart.items, Auth.user.uid)
.then(function(){
PostAffiliatePro.reportSale(Cart.cart.getTotalPrice());
Cart.cart.clearItems();
$scope.mode = 'success';
});
}
);
};
Here's what I think is happening line-by-line...
1) We're declaring a function called handleStripe with two arguments: status and response.
2) A method called processPayment is being called and is inside of an object dependency injected into the controller called PayStripe. .then is opened, so the following lines of code will be executed AFTER the processPayment method is called.
3) Running an anonymous function with an argument of successMessage.
4) I'm confused as to what's happening here, as I've never seen alert called with any arguments other than a message. this page on alert is not much help.
5) A method called recordOrder is called from the object Order which is a dependency of the controller.
6-10) After the recordOrder method is called, the cart is cleared, the sale is reported through another method, and the mode variable contained in the controller's scope is updates to the value success.
I've looked through all of the methods associated with these steps, and I still have some questions.
1) Where are all of these arguments being passed in? Are the arguments passed into the functions pre-declared arguments that will be updated by Angular? I.E. are these variables which Angular defines as the process moves through the queue, and whose values are not user-defined?
2) On line #4, I understand that the second argument is from the argument defined in the function, but what is the combination of these two valued inside the alert() function doing?
3) The fix to the bug that comes from this script depends on me being able to change the value of $scope.mode to something different as soon as the handleStripe function is called, however I have tried to insert such a declaration in multiple places that seem logical with results varying from the script breaking, to nothing happening at all. To me it seems that the logical place to put $scope.mode = 'my-value'; would be between current lines #1 and #2, however this produces the affects I mentioned before.
Finally, I feel I may be missing an overall concept, rather than wrestling with syntax. What is this concept called, if I am missing one, and where can I learn to use it?

Related

Determine function file/line location given reference in NodeJS?

The fact that I can't think of how to do this makes me think it's some sort of anti-pattern, or impossible. If anyone has any better ideas of how to handle my situation, recommendations always welcome.
I have a legacy codebase and at one point I am retrieving function references and calling the function. These function calls are expected to return a result, but sometimes they are missing their return statement. Currently I throw an error if the returned value is nullish but this only gives me a stacktrace to the engine location that is calling the function, not the function itself.
Is there any way that I can determine the file name/number of the function, or force the function to throw an error such that a stacktrace to that actual function is generated?
There is no such feature in the Javascript language. It's not anti-pattern, just not something that the language supports. There is no requirement that a function have a return statement and there is no way to force it to throw an exception if it doesn't return a value.
Without seeing any of the relevant code, I can offer some suggestions:
Set a breakpoint at the line of your code that initiates the function call. Then, trace into the function in the debugger. You can go as far into it as you need to and each time you go step into a new function call, it will show you the file and line number that you're on. I use this technique regularly when I'm confused by some behavior by some module (either built-in to nodejs or an external module I'm using) and it's not immediately clear how to find the right code on Github for it. I just step into it and can immediately see the code and watch it execute line by line as needed for whatever problem I'm investigating.
Assuming this function you're calling expects some arguments, you can give it some sort of bogus arguments that would hopefully trigger it to throw some sort of exception and you could then see the stack trace from that exception. For example, if it was expecting a non-optional object as an argument, you could pass null and see if that triggers an exception. If it was expecting a callback, you could pass a non-function and see if that triggered an exception.
As for the name of the function, if the function has an actual name (it's not anonymous) and fn is your function reference, then you can do console.log(fn.name) and see if there is a name. You could also examine fn.toString() and see if it reveals the source code of the function. Sometimes it will and if the function is a named function that may show you its name. This won't show you what file it's in, but you could perhaps then grep for something you see in the source to find it.
Here's an example from point #3:
function hello() {
return "hi";
}
// create function reference that points to my function
const fn = hello;
// log info on that function reference
console.log(fn.name);
console.log(fn.toString());

JS reference inside function and watch

I have something wrong with the following code. I can't understand what is wrong with it.
function some(){
for (var i=0;i<....;i++)
{
var oneObject;
...some logic where this object is set
oneObject.watch(property,function(id, oldval, newval){
globalFunction(oneObject,id,newval);
return newval;
});
}
}
If I have for example three cycles and set three different objects I have the following result. Three different objects (for example oneObject can be equal some={},some.foo={}, some.boo={}) are set. Every of them has its own watch handler (I change the object and the handler is called). The problem is that when globalFunction is called oneObject that is passed as argument is always equal to the last object of for loop.
I can't understand why it happers as for every new cycle I redeclare oneObject variable using var. Please, explain.
EDIT
Also I tried:
function some(){
for (var i=0;i<....;i++)
{
var oneObject;
...some logic where this object is set
oneObject.watch(property,function(id, oldval, newval){
(function(obj) {
globalFunction(obj,id,newval);
}(oneObject))
return newval;
});
}
}
Since oneObject refers to an object, changing it will also change other references to that object. You can solve this with a closure.
(function(obj) {
globalFunction(obj,id,newval);
}(oneObject))
This way, each time you call globalFunction it will receive a unique copy of oneObject.
You need to create a closure for the entire reference to oneObject:
(function(obj) {
obj.watch(property,function(id, oldval, newval){
globalFunction(obj,id,newval);
return newval;
});
}(oneObject));
(I'm curious what that return is expected to do in a callback, but that's a separate issue.)
It is a little hard to tell from the abstracted code you provided but this looks like a problem caused by using an asynchronous event-loop callback (i.e. the function in watch). What typically happens in situations like this: The main loop sets up a callback. The value changes, triggering the event that is being listened to (i.e. the watch). The callback is queued in the event-loop, which is different from the main executing loop. The callback doesn't get fired until the next open cycle, which might mean the main loop has been executing in the meantime, changing the value more.
It is a little hard to explain here, but here is a link to a wonderful video that will walk you through the details of what might be happening: https://www.youtube.com/watch?v=8aGhZQkoFbQ
I don't think that oneObject persists outside of the scope. You might try using an array of oneObjects so that your oneObject variable doesn't get re-assigned each iteration. It tends to be precarious to declare variables inside of a for loop.

Javascript callback functions differences

I would like to know the difference between 2 implementations of callback functions.
This:
$("#button").on('click', function () {
//do something
});
Versus having the function already defined.
$("#button").on('click', btnFunction);
function btnFunction() {
//do something
}
Are there any implications with one compared to another? Performance-wise is one faster?
The first uses an anonymous function and the second does not. There's no difference in both.
See:
Why do you need to invoke an anonymous function on the same line?
Some folks prefer the second form because it gives a function name when using the debugger and tracing, but there are ways to get the same functionality in the first form.
If you are attaching and removing the event handler based on changing conditions, the second form is much easier to maintain, however.
There's no difference at all, and there's no performance issue with neither one of them. The only difference is that in one of them you're defining the callback function as an anonymous function, this way you cannot reuse it.
The other way, where you define it else where and named it and then pass it as a callback, you're defining a function that you can later reuse in another part of your code.
For example: if you want to do something when the document is ready, and then do se exact same thing when some one press a button you can use something like this:
function getData() {
//do something
}
$(function() {
// Call the function once the DOM is ready
getData();
});
// Call the same function when the button is clicked
$("#refresh_button").on('click', getData);
In most cases the first one will be used, called Anonymous Functions
The second one will be used when the function is not only used inlined here, but also needs to be reused somewhere else.
But anyway it could be a personal preference.
The only real difference you could see is that stack trace (if an exception is thrown for example) will be better, i.e. easier to debug, when using the second one.
Just reuse-ability.
In the second case, you could call btnFunction() somewhere else if need be.

Does the use of prototyping in javascript have a negative effect on ajax calls and asynchronous code?

If I had the following object and prototyped functionality added on.
function Hello (input){
this.input = input
}
Hello.prototype.ajaxcall = function(id){
$.get("/ajax/method", {parameter:input}, function(data){
$("#"id).html(data);
});
}
Forgive the syntax if not completely correct but what it should be doing is taking in an element id, performing an ajax call and assigning the ajax call result to the innerHTML of the id. Will the fact that the ajaxcall function is shared across all instances of an object cause any problems with regards to what data will be assigned to which id if for example 20 object were all created together and had this function called immediately?
If this is the case, does it make sense to put asyncronous methods inside the object constructor instead?
What would happen if 20 objects would be created and the ajaxcall function would be called? Nothing much. The ajax calls would run asynchronously. When they have finished they are queued so that they run on the main thread when the current running operation on the main thread finished.
So the callback functions run all synchronous in a queue next time there's time for it. Nothing bad can happen here.
I don't understand your question about the constructor. What would that change? If you use your Hello objects they have an instance variable. This is is enclosed in the callback closure . Creating a new function doesn't change the value in another callback function.
If you use the same IDs the content could flash when the text changes and you don't know which callback would be ran last but that's the worst thing that could happen.
There should be no issue. You're calling the function 20 distinct times with 20 different ids.
Conceptually though. I'm not seeing why this is part of your object. The function does not use anything at all from the object itself.
This particular example would work. Your function makes no use of any instance variables, so it doesn't really make sense to declare it that way, but it makes even less sense to move it into the constructor. Still it will work because the id argument will not be shared between calls.
EDIT: So now that you've changed it so that it does use an instance variable you've got the syntax wrong, it needs to be
{parameter : this.input}
But aside from that it will still work. The asynchronous behaviour is not a problem for the code shown.

Using Firebug and jsfiddle.net to test a function

Im a newbie programmer who got the function below from Stoyan Stefanovs object oriented JavaScript Book. He says that if you call next three times, it will output "a" and "b" and then "c". When I tried it in firebug console, it kept giving me "a", so that`s one question (a) i.e. is there something about firebug that would explain my result?
Next, I tried to run it in jsfiddle.net but it won`t output anything. http://jsfiddle.net/mjmitche/SkSMm/
Im sure Im doing something wrong, but what? Please explain if you can. Note, I did next(); and got A, and then I did next(); again and got 'a' and next(); again and got 'a'. In other words, the counter didnt change or didnt remember.
function setup(x) {
var i = 0;
return function () {
return x[i++];
};
}
var next = setup(['a','b','c']);
next();
Here is the jsfiddle link to show it works:
http://jsfiddle.net/ZnZTk/
JsFiddle is not like the console, it doesn't have a window where it will output return values. The result of the code is a web page, that is shown at the lower right.
You can use the alert method to show the values:
alert(next());
http://jsfiddle.net/SkSMm/4/
As you see, calling next three times will actually output the three values in the array. The setup function returns a delegate to the anonumous function that is created in the function. As that anonymous function uses variables outside itself, but which are local to the surrounding function, a closure is created for the function. The closure will contain the i and x variables. As the closure belongs to the delegate, it will survive from one function call to the next, and retain the values of it's variables.
You could do a similar thing just using global variables:
var x = ['a','b','c'];
var i = 0;
function next() {
return x[i++];
}
alert(next());
alert(next());
alert(next());
As the variables are declared outside the function, they will survive between the function calls.
The drawback of using global variables is that one script easily clashes with another if the variables are not given very unique names. If you use a closure, there is no risk of the variables of one script to conflict with variables of another script.
You did it wrong:
And jsfiddle: http://jsfiddle.net/ZHgW2/
Here's a neat demo that takes advantage of an imported say function and relies on a button:
http://jsfiddle.net/entropo/wxTqR/
This is a great way to test your scripts without relying on the log or alerts.
The say function is from jQuery in Action. Excerpt:
Within this function, we employ the services of a small utility function, say() C,
that we use to emit text messages to a dynamically created element on the page
that we’ll call the “console.” This function is declared within the imported support
script file (jqia2.support.js), and will save us the trouble of using annoying and disruptive alerts to indicate when things happen on our page. We’ll be using this handy function in many of the examples throughout the remainder of the book.

Categories