Getting an image in Base64 format as global variable - javascript

I am trying to get image in Base64 format outside of
var codedPic;
var purl = 'http://upload.wikimedia.org/wikipedia/commons/4/4a/Logo_2013_Google.png';
var codedPic = convertImgToBase64(purl, function(base64Img){ console.log('attempt 1: ' + base64Img); });
console.log('attempt 2: ' + codedPic);
It is getting results of attempt 1 but for attempt 2 it displays undefined. But I need it working too. Can anyone help me please?
Please feel free to amend this jsfiddle: http://jsfiddle.net/s7x0otdc/2/

(in fiddle) after you complete the conversion, you call callback, therefore nothing is stored in codedPic variable.
you can fix it by using return codedPic; instead of using callback
or you can do everything you need in that callback function (because after completing callback function you lose "hers" variables)
i suppose there is some way with global vars.. but just now i don't know how i would do that

EDIT:
New demo to show you how to modularize your code. The encoded picture is available outside of your conversion function (more precisely in your global variable codedPic). But you have to wait for your callback to be triggered to be sure it now has the correct value.
http://jsfiddle.net/s7x0otdc/7/
Well you have several mistakes in your code.
As pointed out by Jimmmy, your function does not return anything, so the assignment var codedPic = convertImgToBase64(purl /* ... */ ); is useless as codedPic will remain undefined.
Time to read How to return the response from an asynchronous call? to understand why you need to use callbacks, and that you have to put any code that depends on a server response inside a callback. Since your conversion function needs to wait for the load event of your image, you will get data into dataURL at an unkown moment in the future. When this moment arrives, JS will trigger your callback and give it that data as argument, as per your conversion function specifies. So only your callback can safely assign your desired data into a global variable, and trigger any action that depend on that data.
Demo: http://jsfiddle.net/s7x0otdc/5/

Related

Fundamental misunderstanding of how Angular handles a snippet?

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?

JS / Jquery .load and .length

I'm new to Jquery/javascript with almost all of my experience being in PHP. I am now finding the importance of how things are ordered :)
So I'm trying to load some <div>s into the container #text-container using .load and then count them. My understanding of jquery's load function is that the 2nd argument is a callback function which will only run once all data has been loaded. But it is always reported as 0 even if there are 4-5 divs being placed in the container. Am I missing something?
1.txt
<div>1</div><div>2</div>
Code:
$("#text-container").load("1.txt",alert($("#text-container div").length));
This is just an example but I need to use that number to do a whole bunch of maths in other functions. So if I call those instead of alert and try to run .length in there they all get 0 and my math doesn't work :(
Ideas?
You need an anonymous function for the callback
$("#text-container").load("1.txt", function(data) {
alert( $("#text-container div").length )
});
This is just an example but I need to use that number to do a whole
bunch of maths in other functions.
Note that it's async, so you can't use it until it's actually there, and why would your .txt file contain DIV elements, seems like the wrong file extension to me ?
Answer
$("#text-container").load('1.txt',function(){
alert($("#text-container div").length);
});
Explaination
First let us talk about the callback function passing, the right syntax:
$(selector).load(source,callback);
Suppose you have some function named as gg and we want to use it in place of callback
function gg(){
//some code for task 1
}
now lets use it as callback
(the wrong way)
$(selector).load(source,gg());
Note: when you write the function with parenthesis (), the function is called at the same time, so you just need to pass the identifier
(the right way)
$(selector).load(source,gg);
OR USE ANONYMOUS FUNCTION
$(selector).load(source,function(){
// some code for task 1
});
Note: Instead of defining a function only for callback and if you are not using it again it is preferred to use anonymous function
You are not doing what you think you do. You pass the result of alert() as an argument.
$("#text-container").load("1.txt",alert($("#text-container div").length));
is equivalent to :
var data = alert($("#text-container div").length); // data = 0
$("#text-container").load("1.txt", data);
What you want is to pass a function as an argument :
var callback = function() {
alert($("#text-container div").length);
}
$("#text-container").load("1.txt", callback);
or shorter :
$("#text-container").load("1.txt", function() {
alert($("#text-container div").length);
}

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.

Edit Javascript function

Is it possible to edit a JavaScript function after the page has loaded?
I want to edit a function dynamically after Loading.
You can't edit a function, but you can replace it, e.g.:
var myFunc = function() { return "Hello World"; };
myFunc = function() { return "Goodbye"; };
javascript functions are objects, so can be replaced by setting a new value. Is this what you mean?
Unless you are trying to hack some code that doesn't belong to you, the better solution is to write a more flexible initial javascript function who's behavior can be adapted based on conditions (parameters passed, environment, other state, data fetched from other sources, etc...). Then, the one function you have can be written once initially to handle all your different circumstances.
You can even use design patterns such as passing in callback functions that can be used to adapt the behavior at runtime. If you desire many callbacks, you can pass in an object that has a number of different optional methods and call those during your function. In this way you can significantly alter the behavior of the main function without ever changing it's code by passing in different callback functions.
For example, let's assume we have a parsing function that takes some tagged data structure as input and returns an array of results. We want to be able to modify the behavior of this parsing function by passing in callbacks. So, we write the parsing function to take a callback object. That callback object contains one or more methods (all of which are optional) and a state variable that is passed to each callback. Anyone who has worked with ajax or any asynchronous networking in Javascript will recognize the callback object concept. Here's some pseudo code for such a process that shows how the callback object can be used. A real function would obviously be a lot more involved than this one, but it hopefully illustrates the concept:
function parseMyData(data, callbacks) {
var output = []; // output we accumulate
var currentTag;
callbacks = callbacks || {}; // make the callbacks object optional
// do any preprocessing that the caller specified
if (callbacks.preProcessData) {
data = callbacks.preProcessData(data, callbacks.state);
}
[[code to parse to the first tag in the data (after doing so currentTag contains the tag we just parsed)]]
// give our callback object the opportunity to do something to this tag or return null to skip it
if (callbacks.preProcessTag {
currentTag = callbacks.preprocessTag(currentTag, callbacks.state);
}
if (currentTag) {
[[code here for the default processing of the tag that will push results into the output array]]
}
return(output);
}
If you want to add an action to the existing function you can "hijack" it by putting it in a temporary variable and calling it within your overwritten function. E.g.
// The original function.
function sayName(name) {
alert(name);
}
// Temporary variable for original function.
var __sayHello = sayName;
// Overwrite the original function, adding extra actions.
sayName = function(name) {
alert('Hello');
// Call the original function using its temporary variable.
__sayHello(name);
}
// Call the overwritten function.
sayName('Bob');
How to edit a function - 101.
If we reconsider that editing a function at runtime is not absolutely changing the guts of the function, but rather changing what the function guts are digesting, then I would say functions are already built to do just that.
example 1 - The guts cannot be changed.
function one(){
return true;
}
// one() => true;
// Note: We could still change the output without changing the guts.
// !one() => false;
example 2 = The guts can be created to digest a dynamic call.
function one(payload){
return payload;
}
// one(true) => true;
// one(false) => false;
// one('whatever I want to feed the guts to digest');
// => 'whatever I want to feed the guts to digest';
These are quite simple examples, but since you did not provide any real examples as to what you are trying to do, we have to assume you are attempting normal patterns of programming.
Considering NORMAL patterns of programming, it wouldn't be the function itself that needs to change, rather how you are calling it.
example 3 - Give the choice of which function to the caller.
function firstChoice(payload){
return http.post(payload);
}
function secondChoice(choice){
return `Do something else with ${choice}`;
}
// And where you make the choice, perhaps after a click event handler...
function onClick(choice, payload){
choice ? firstChoice(payload) : secondChoice(choice);
}
Functions are supposed to be small bricks with which you build logic. Give them something small to do, then select between them based on your logic.
To answer your question, in my opinion, assuming normal programming needs...
"Is it possible to edit a JavaScript function after the page has loaded?" YES.
Use arguments in your function definition to add the dynamic ability to suit your needs.

Why is dynamically modifying a JavaScript function's code mid-execution a bad thing?

A few days ago, I asked a question regarding dynamically modifying a function's code midway through the outerlying script's execution and I was told to completely forget ever coming upon the notion. I'm not sure I understand why that is. Let me give an example:
<script>
var display = function(msg)
{
alert(msg);
}
// Now, at the moment, the display() function
// is receiving a single parameter and alerting
// it to the user. I'm now going to use eval()
// to modify the display() function.
eval('display = ' + display.toString().replace('alert(', 'document.write('));
// Now, the display() function writes its parameter
// to the document as opposed to alerting it.
</script>
I realize this is a rather trivial example, but there must surely be some use that can be derived from being able to dynamically modify a function, something so useful by itself.
Although this may do what you need it to do, 6 months from now you (or the person maintaining your code) will be going "WTF?!"
If your use case is to alert or write based on some condition, why don't you write two different functions? Or have your function take another parameter that decides the output mode. Or pass in a function as a parameter that performs the actual output. Something, you know, a little more on the sane side. ;-)
There are cases where it could be useful to change a function's behavior, but there are better ways to do it. In your example, you could create new instances of the function that handle the output differently, by passing a function as an argument (similar to the strategy pattern):
function makeDisplay(displayStrategy) {
return function(msg) {
// I'm assuming you would do some additional processing here...
displayStrategy(msg);
}
}
var display = makeDisplay(alert);
// now modify display to use document.write
display = makeDisplay(function(msg) { document.write(msg); });
Well, using eval might be a security concern but modifying a function in real-time is ok. How else you can make memoization anyway?
Although, come to think of it, changing method signature isn't a great idea, other people won't know how to call this function after this, since it would depend on execution order and it's not easy to track usually.
I have found myself needing to do this in situations where I don't have the source code for a particular piece of vendor javascript; so that could be a legitimate use case. I agree that if you have another option, it's better to do it in a more organised way, editing the original function to be more flexible.

Categories