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.
Related
Below is the code.
under the function there is a resultContainer.innerHTML that populates a list of QR codes scanned. How can $_POST the values in PHP so that I can send it in an email format? I tried adding a name within the div (<div **name="qrOutput"**>[${countResults}] - ${qrCodeMessage}</div>) but PHP does not pick it up. Only returns an empty string.
I also tried giving the <div id="qr-reader-results"></div> element a name but because the output is within another div inside this div I also got an empty result.
Thanks a lot for any help.
<!-- start -->
<div id="qr-reader" style="width:500px"></div>
<div id="qr-reader-results"></div>
<div id="root"></div>
<script>
function docReady(fn) {
// see if DOM is already available
if (document.readyState === "complete" ||
document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
docReady(function() {
var resultContainer = document.getElementById('qr-reader-results');
var lastResult, countResults = 0;
function onScanSuccess(qrCodeMessage) {
if (qrCodeMessage !== lastResult) {
++countResults;
lastResult = qrCodeMessage;
resultContainer.innerHTML += ***`<div">[${countResults}] - ${qrCodeMessage}</div>`;***
}
}
var html5QrcodeScanner = new Html5QrcodeScanner(
"qr-reader", {
fps: 10,
qrbox: 250
});
html5QrcodeScanner.render(onScanSuccess);
});
</script>
<p id="QRout"></p>
You can store your results in an other variable when you add it to the DOM.
Declare a variable to store your results
var myResults = [];
When you add the result to the DOM add also the results in array variable
// ...
resultContainer.innerHTML += `<div>[${countResults}] - ${qrCodeMessage}</div>`;
myResults.push({count: countResults, message: qrCodeMessage})
Then you can use myResult var on a POST request
myCustomPostFunction('/yourUrl/', myResult);
The "myCustomPostFunction" will depend on the way you want to send the data
Check this codepen: https://codepen.io/zecka/pen/VwKNpze
Post request like a form submit
If you want to send the data to the current page like a form post, you can find an example here: https://stackoverflow.com/a/133997/2838586
Post request to a rest api
Fetch: POST json data
Attempting to create a script that will pull information from an API requested XML document and put it into a 2D array.
Upon making the Get request
https://api.example.com/v1.svc/users?apikey=MY-KEY&source=MY-APP&limit=1000
An XML is produced for each user looking like
<User>
<Id>Rdh9Rsi3k4U1</Id>
<UserName>firstlast#email.com</UserName>
<FirstName>First</FirstName>
<LastName>Last</LastName>
<Active>true</Active>
<Email>firstlast#email.com</Email>
<AccessLevel>Learner</AccessLevel>
</User>
Each user has a similar looking output stacked on top of each other. How could this be scrubbed into an array? Example, the first array would have 7 "columns" with all shown information with each user having a row.
b
So I figured it out for anyone looking for an answer to this type of question in the future. Basically, I found out that the API I was trying to reach (not actually "citrowske.com" as shown in the example) did not allow for CORS or jsonp which left me with the only option of using a Proxy.
Shown is an example of code similar to what I ended up using (below), along with the test XML file shown here
A basic explanation of how this works, it uses the proxy to get the XML file and stores it as "xml" found as "function(xml)". Then the XML doc is searched and each section that starts with "User" gets the "FirstName" and "LastName" data pulled from it and appended to dropdown in the HTML section named "yourdropdownbox".
$.ajaxPrefilter( function (options) {
if (options.crossDomain && jQuery.support.cors) {
var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
//options.url = "http://cors.corsproxy.io/url=" + options.url;
}
});
$.get(
'http://citrowske.com/xml.xml',
function (xml) {
//console.log("> ", xml);
//$("#viewer").html(xml);
////////////////////////////////////
var select = $('#yourdropdownbox');
select.append('<option value="">Select a User</option>');
$(xml).find('User').each(function(){
var FirstNames = $(this).find('FirstName').text();
var LastNames = $(this).find('LastName').text();
select.append("<option value='"+ FirstNames +"'>"+FirstNames+" "+LastNames+"</option>");
});
}
////////////////////////////////////
);
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<select id="yourdropdownbox">
</select>
As a note, Proxy's are not known for being extremely secure, so watch out what you use this for.
Also, if I wanted to turn the data into an array instead of appending it each time I could have added
var firstnamesarray = ["0"];
var lastnamesarry = ["0"];
var i = 0;
Above the top row of forward-slashes and then replaced:
var FirstNames = $(this).find('FirstName').text();
var LastNames = $(this).find('LastName').text();
with
firstnamesarry[i] = $(this).find('FirstName').text();
lastnamesarry[i] = $(this).find('LastName').text();
i = i+1;
and replaced the "select.append" First & Last Names with
firstnamearry[i] & lastnamearry[i]
To view a working example, check out the jsfiddle here
I am doing:
var url = '#Url.Action("Attachments", "Transactions")';
url += '/?id=' + 3201;
$("#attachments").load(url);
However, on load it doesn't do anything. Am i missing something?
I essentially want to call something similar to:
#{Html.RenderAction("Attachments", "Transactions", new { id = 3301 });}
I get the following error on console:
http://server:54137/Transactions/#Url.Action(%22Attachments%22,
You must be using an external JavaScript file which will not parse your razor syntax hence the error in your console of #Url.Action(%22Attachments%22..
You have a couple of options:
Create a JavaScript function and pass in the url:
function loadUrl(url) {
$("#attachments").load(url);
}
Then in your razor call it within a script tag:
loadUrl(#Url.Action("Attachments", "Transactions", new { id = #Model.Id })
Add the url to the html element as data and read it from your JavaScript with the data method.
In your razor markup add this:
<button data-url="#Url.Action("Attachments", "Transactions", new { id = #Model.Id })" />
From your JavaScript event handler read it with:
var url = $(this).data('url');
$("#attachments").load(url);
I prefer the second option.
You Need to use Html.Raw check below
var url = "#Html.Raw(Url.Action("Attachments", "Transactions"))";
url += '/?id=' + 3201;
$("#attachments").load(url);
I have written a function to display some paragraph tags from an external webpage. For some reason the results are displayed in firebug console but not showing on the web page as I wanted (blank page).
function requestCrossDomain(callback){
var querylink = "select * from html where url='http://somedomain.com'" +
" and xpath='/html/body/div/div/div[2]/div/div/div/dl'";
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' +
encodeURIComponent(querylink) + '&format=json&callback?';
$.getJSON(yql, function(data){
if (typeof callback === 'function'){
callback(data);
}
});
}
My firebug console shows the below value.
{"query":{"count":1,"created":"2013-12-23T06:31:46Z","lang":"en-US","results":{"dd":{"p":"Hills: High"}}}}
How can I modify the code to display the value of the P tag, which is "Hills: High"
I'm calling the function from HTML code and trying to display the value inside "#targetWrapper"
requestCrossDomain(function(results){
$('#targetWrapper').html(results);
});
Edited to reflect a functional fiddle
$(document).ready(function(){
requestCrossDomain();
});
function requestCrossDomain(){
var querylink = "select * from html where url='http://www.bom.gov.au/wa/forecasts" +
"/armadale.shtml' and xpath='/html/body/div/div/div[2]/div/div" +
"/div/dl'";
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' +
encodeURIComponent(querylink) + '&format=json&callback?';
$.getJSON(yql, function(data){
$('#targetWrapper').html(data.query.results.dl.dd[0].p);
$("#targetWrapper").append("<br/><strong>" + JSON.stringify(data) + "</strong>");
});
}
Your data format was very much off the mark AND you cannot have two functions with the same name.
The object you get back from $.getJSON is a simple Javascript Object. You can access it just as you would any other object:
In this case, you'd use:
requestCrossDomain(function(results) {
$("#targetWrapper").html(results.query.results.dd.p);
}
I would highly recommend that you read the MDN documentation I linked above. Having MDN bookmarked is also a good idea; it's a great resource to have easy access to.
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/>')