I am making a website that grabs data from an API. The API essentially consists of a script normally ran as such
<script type="text/javascript" src="https://www.fxblue.com/users/dynascalp_demo/overviewscript"></script>
it will simply create an array and push the data I need from it, like this:
if (!document.MTIntelligenceAccounts) document.MTIntelligenceAccounts = new Array(); document.MTIntelligenceAccounts.push({ "userid": "dynascalp_demo","balance": 9275.95,"equity": 9275.95,"closedProfit": -724.05,"floatingProfit": 0,"freeMargin": 9275.95,"totalDeposits": 10000,"totalWithdrawals": 0,"totalBankedGrowth": -7.24,"monthlyBankedGrowth": -0.67,"weeklyBankedGrowth": -0.16,"dailyBankedGrowth": -0.03,"bankedProfitFactor": 0.66,"deepestValleyCash": -819.04,"deepestValleyPercent": -8.19,"troughInBalance": 9175.79,"peakInBalance": 10020.11,"historyLengthDays": 331,"averageTradeDurationHours": 2.17,"worstDayPercentage": -1.44,"worstWeekPercentage": -2.32,"worstMonthPercentage": -4.31,"tradesPerDay": 2.5,"totalClosedPositions": 589,"totalOpenPositions": 0,"bankedWinningTrades": 382,"bankedLosingTrades": 207,"bankedBreakEvenTrades": 0,"bankedWinPips": 1486.3,"bankedLossPips": -1604.6,"initialDeposit": 10000,"totalBankedPips":-118.3,"totalOpenPips":0,"peakPercentageLossFromOutset": -8.24,"riskReturnRatio": -1.21,"openAndPendingOrders": []});
My idea is to run this code conditionally, in another, bigger script. I will query my database and check whether the data is already in the database. If it is, then skip the request altogether and send the data from the database through an ajax request handled by the server, which will return a JSON. If it isn't or the data has expired, meaning it has not been updated for at least a day, it should grab the data from the API and update the database. This is done by the front-end as there is no Node.js support in the back-end.
The only thing I'm missing is how I should execute this script from mine, instead of calling it directly in the HTML.
For example, Fetch() does not work. I believe the request is malformed, or it is not the type of request it expects. Unexpected end of input is thrown and the request does not succeed.
This code should result in a number being shown
function fxBlue_retrieveAPI() {
document.MTIntelligenceAccounts = new Array();
const url = "https://www.fxblue.com/users/dynascalp_demo/overviewscript";
//var fxblue_API_Names = ["dynascalp_demo", "fxprogoldrobot", "fxprosilverrobot", "forex_gump_ea"];
var varNames = ["totalDeposits", "balance", "totalBankedGrowth", "monthlyBankedGrowth", "deepestValleyPercent", "historyLengthDays"];
var experts = [];
var s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("src", url);
document.body.appendChild(s);
for (var i = 0; i < document.MTIntelligenceAccounts.length; i++) {
experts.push({ name: document.MTIntelligenceAccounts[i].userid, id: i });
if (document.getElementById(experts[i].name + varNames[0])) { document.getElementById(experts[i].name + varNames[0]).innerHTML = document.MTIntelligenceAccounts[experts[i].id].totalDeposits; }
if (document.getElementById(experts[i].name + varNames[1])) { document.getElementById(experts[i].name + varNames[1]).innerHTML = document.MTIntelligenceAccounts[experts[i].id].balance; }
if (document.getElementById(experts[i].name + varNames[2])) { document.getElementById(experts[i].name + varNames[2]).innerHTML = document.MTIntelligenceAccounts[experts[i].id].totalBankedGrowth + "%" };
if (document.getElementById(experts[i].name + varNames[3])) { document.getElementById(experts[i].name + varNames[3]).innerHTML = document.MTIntelligenceAccounts[experts[i].id].monthlyBankedGrowth };
if (document.getElementById(experts[i].name + varNames[4])) { document.getElementById(experts[i].name + varNames[4]).innerHTML = document.MTIntelligenceAccounts[experts[i].id].deepestValleyPercent + "%" };
if (document.getElementById(experts[i].name + varNames[5])) { document.getElementById(experts[i].name + varNames[5]).innerHTML = document.MTIntelligenceAccounts[experts[i].id].historyLengthDays };
}
}
<script type="text/javascript" src="/cdn-cgi/scripts/API/jquery-3.1.1.min.js" async></script>
<script type="text/javascript" src="/cdn-cgi/scripts/API/test.js"></script>
<body onload="fxBlue_retrieveAPI()">
<h3>Total banked growth data example</h3>
<p id="dynascalp_demototalBankedGrowth"></p>
</body>
Assuming (or hoping) that you won't experience CORS problems with your data source (here at SO it is not possible to reach the source), you could do something like this to get to the actual contents of the script file:
const actualText=`if (!document.MTIntelligenceAccounts) document.MTIntelligenceAccounts = new Array();\ndocument.MTIntelligenceAccounts.push({\n"userid": "dynascalp_demo","balance": 9275.95,"equity": 9275.95,"closedProfit": -724.05,"floatingProfit": 0,"freeMargin": 9275.95,"totalDeposits": 10000,"totalWithdrawals": 0,"totalBankedGrowth": -7.24,"monthlyBankedGrowth": -0.67,"weeklyBankedGrowth": -0.16,"dailyBankedGrowth": -0.03,"bankedProfitFactor": 0.66,"deepestValleyCash": -819.04,"deepestValleyPercent": -8.19,"troughInBalance": 9175.79,"peakInBalance": 10020.11,"historyLengthDays": 331,"averageTradeDurationHours": 2.17,"worstDayPercentage": -1.44,"worstWeekPercentage": -2.32,"worstMonthPercentage": -4.31,"tradesPerDay": 2.5,"totalClosedPositions": 589,"totalOpenPositions": 0,"bankedWinningTrades": 382,"bankedLosingTrades": 207,"bankedBreakEvenTrades": 0,"bankedWinPips": 1486.3,"bankedLossPips": -1604.6,"initialDeposit": 10000,"totalBankedPips":-118.3,"totalOpenPips":0,"peakPercentageLossFromOutset": -8.24,"riskReturnRatio": -1.21,"openAndPendingOrders": []});`;
// fetch("https://www.fxblue.com/users/dynascalp_demo/overviewscript")
fetch("https://jsonplaceholder.typicode.com/users/3") // (some dummy data source for demo purposes only)
.then(r=>r.text())
.then(text=>{ text=actualText; // mimmic the text received from www.fxblue.com ...
obj=JSON.parse(text.replace(/(?:.|\n)*push\(/,"").replace(/\);$/,""))
console.log(obj)
})
It is then up to you to decide whether you want to use the data or not.
Whatever you do, it is important that the action happens in the callback function of the last . then() call. Alternatively you can of course also work with an async function and use await inside.
My idea is to run this javascript code conditionally, by querying my database
For this you could do an jquery ajax call, and act based on the response you get. I recommend using jquery for the ajax call. Here is the jquery ajax call where you pass whatever data is necessary to the controller.
$.ajax({
type: "GET",
url: "/ControllerName/ActionName",
data: { data: UserIdOrSomething },
success: function(response) {
// you can check the response with an if, and implement your logic here.
}
});
You can place this ajax call in the document.ready function to automatically call it whenever the page loads.
$( document ).ready(function() {
// place the above code here.
});
As an example, here is how an asp.net core controller action would look like that would handle this ajax call;
[HttpGet("ActionName/{data:string}")]
public IActionResult ActionName(string data) // parameter name should match the one in jquery ajax call
{
// do stuff. query your database etc.
var response = "the response";
return Json(response);
}
finally, keep in mind handling sensitive data in javascript is generally not a good idea, as the javascript code is open to everyone. For example, in this case, you will be giving out a way for people to check if a user exists in your database, which could be problematic. I would suggest using guid as id for the users table if possible, which may or may not be useful to mitigate the dangers depending on how you query the database.
I am trying to create a URL shortener using jsonbase.com and vanilla javascript.
button tag in HTML was not able to recognize the method "shortUrl" from my js file. So, I directly added the code of add event listener in the js file.
index.html
<body>
<div id="app">
<input type="url" id="urlinput">
<input id="mybutton" type="button" value="Short the URL"/>
</input>
</div>
<script src="src/index.js"></script>
</body>
Now, I am getting an error - Javascript type error - The "listener" argument must be of type Function. Received type object - when I am trying to use jsonbase.com for storing the data.
script.js
function shortUrl() {
var longurl = getURL();
genHash();
var uniqueHash = window.location.hash.substr(1);
sendRequest(longurl, uniqueHash);
if (window.location.hash !== "") {
var short = getRequest(uniqueHash);
if (short !== "") {
window.location.herf = "short";
}
}
}
use of jsonbase.com
var jsonbase = require("jsonbase.com");
var token = "mytoken";
var store = jsonbase(token);
var endpoint = `jsonbase.com/${token}`;
//sending request
function sendRequest(longURL, uniqueHash) {
store.write(`${endpoint}/${uniqueHash}`, longURL);
}
//getting request
function getRequest(uniqueHash) {
return store.read(`${endpoint}/${uniqueHash}`).then((response) => {
return response.data;
});
}
generating hash for shorter
function genHash() {
if (window.location.hash === "") {
window.location.hash = getRandomStr();
}
}
Error screenshot -
I have created a reproducible sample code sandbox for my private application - https://codesandbox.io/s/url-shortner-t3ov2
Please let me know if any more info is required.
The issue is not your code, the issue is the package not parsing the JSON correctly, try using a different package
I know this does not answer your question, but it should solve it
Motivation: I want to make a browser-based hashing utility so users can compute file hashes without installing software.
The approach I'm considering is a static page with "a file upload button" (except no upload takes place): the user picks a file, and the script computes and displays its hash.
So let's say we have this element on the page:
<input id="file-hasher" type="file" />
This creates a button that allows the users of the web page to select a file via an OS "File open..." dialog in the browser.
Let's say the user clicks said button, selects a file in the dialog, then clicks the "Ok" button to close the dialog.
The selected file name is now stored in:
document.getElementById("file-hasher").value
Here, I'm hoping to use a library like https://github.com/bitwiseshiftleft/sjcl/ to compute the hash of the chosen file. Is there a way to do this or does the browser's security model get in the way?
Yes, you can select a file using the file element, and take a hash of the file locally, 'in-browser', using javascript. The browser's security model does not prevent this; and the hash function from the native Web Crypto API can be used, so there is no need for any external crypto libraries.
Here is a working example:
function hashfile() {
readbinaryfile(fileselector.files[0])
.then(function(result) {
result = new Uint8Array(result);
return window.crypto.subtle.digest('SHA-256', result);
}).then(function(result) {
result = new Uint8Array(result);
var resulthex = Uint8ArrayToHexString(result);
divresult.innerText = 'result: ' + resulthex;
});
}
function readbinaryfile(file) {
return new Promise((resolve, reject) => {
var fr = new FileReader();
fr.onload = () => {
resolve(fr.result)
};
fr.readAsArrayBuffer(file);
});
}
function Uint8ArrayToHexString(ui8array) {
var hexstring = '',
h;
for (var i = 0; i < ui8array.length; i++) {
h = ui8array[i].toString(16);
if (h.length == 1) {
h = '0' + h;
}
hexstring += h;
}
var p = Math.pow(2, Math.ceil(Math.log2(hexstring.length)));
hexstring = hexstring.padStart(p, '0');
return hexstring;
}
<h2>File Hash</h2>
<div>
Select file to take hash of:
<br/>
<input type="file" id="fileselector" onchange="javascript:hashfile();">
</div>
<br/>
<div id="divresult"></div>
The standard browser security model allows you to have the user pick a file and do what you will with it. I'm an older guy and thought surely this kinda mingling with a user's parts would require additional hoops/consent. So #ceving 's answer was best: "Do it and you will see."
Here's a link to a good article: https://humanwhocodes.com/blog/2012/05/08/working-with-files-in-javascript-part-1/
Apologies for not trying first before posting.
I'm attempting to display a list of members of a Meetup group, using their API, see https://api.meetup.com/2/profiles?&sign=true&photo-host=public&group_urlname=pipeline-marketing&page=20.
Specifically I'm trying to display the profile photos of all the members of this specific group in HTML. I tried modifying some code found at http://www.jquerybyexample.net/2013/04/how-to-display-load-images-from-json-file-jquery.html but am having some difficulties. The page is blank. I'm not running it locally.
What am I doing wrong?
<div id="members"></div>
<script>
$(document).ready(function () {
var memberURL = "https://api.meetup.com/2/profiles?&sign=true&photo-host=public&group_urlname=pipeline-marketing&page=20";
$.getJSON(memberURL, function (json)
{
var imgList= "";
$.each(json.results, function () {
imgList += '<li><img src= "' + this.photo_url + '"></li>';
});
$('#members').append(imgList);
});
});
</script>
Thank you!
this is my first time here as a poster, please be gentle! I have zero knowledge of JS (yet, working on it) but am required to do some JS anyway. Here's my problem. I got some code (not mine) allowing a user to select multiple choices. I found the function that gathers these choices and store them
function getProductAttribute()
{
// get product attribute id
product_attribute_id = $('#idCombination').val();
product_id = $('#product_page_product_id').val();
// get every attributes values
request = '';
//create a temporary 'tab_attributes' array containing the choices of the customer
var tab_attributes = [];
$('#attributes select, #attributes input[type=hidden], #attributes input[type=radio]:checked').each(function(){
tab_attributes.push($(this).val());
});
// build new request
for (var i in attributesCombinations)
for (var a in tab_attributes)
if (attributesCombinations[i]['id_attribute'] === tab_attributes[a])
request += '/'+attributesCombinations[i]['group'] + '-' + attributesCombinations[i]['attribute'];
$('#[attsummary]').html($('#[attsummary]').html() + attributesCombinations[i]['group']+': '+attributesCombinations[i]['attribute']+'<br/>')// DISPLAY ATTRIBUTES SUMMARY
request = request.replace(request.substring(0, 1), '#/');
url = window.location + '';
// redirection
if (url.indexOf('#') != -1)
url = url.substring(0, url.indexOf('#'));
// set ipa to the customization form
$('#customizationForm').attr('action', $('#customizationForm').attr('action') + request);
window.location = url + request;
}
I need to make a simple display summary of these choices. After quite a bit of searching and findling, I came with the line with the DISPLAY SUMMARY comment, this one:
$('#[attsummary]').html($('#[attsummary]').html() + attributesCombinations[i]['group']+': '+attributesCombinations[i]['attribute']+'<br/>')
In the page where I want those options, I added an empty div with the same ID (attsummary):
<div id="attsummary"></div>
Obviously, it is not working. I know I don't know JS, but naively I really thought this would do the trick. May you share with me some pointers as to where I went wrong?
Thank you very much.
Correct form of the line it isn't working for you:
$('#attsummary').html($('#attsummary').html() + attributesCombinations[i]['group']+': '+attributesCombinations[i]['attribute']+'<br/>')