-2

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>
  • 1
    Does this answer your question? [Dynamically load a JavaScript file](https://stackoverflow.com/questions/21294/dynamically-load-a-javascript-file) – jabaa Jan 31 '23 at 20:53
  • I have tried the `document.body.appendChild(s)` method, but the array is still not initialized meaning that the script is not being run – Eduardo Meli Jan 31 '23 at 21:06
  • In that case you should provide a [mcve] as text in your question. – jabaa Jan 31 '23 at 21:10
  • @EduardoMeli Perhaps you are checking for the array too early, before it was downloaded and run. You could listen to its `load` event. – CherryDT Jan 31 '23 at 21:12
  • The script contains a function. You can conditionally call the function. – jabaa Feb 01 '23 at 13:40

2 Answers2

-1

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.

Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
  • I am not sure, but the fetch() does not work on the fxblue API. At this point the goal would be to retrieve the data as text and completely disregard the array creation part and pull the data directly – Eduardo Meli Feb 01 '23 at 12:31
  • The external script reads a database. The data isn't hard coded in the script. You can't parse it. You have to evaluate it. – jabaa Feb 01 '23 at 13:36
-1

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.

Emre Bener
  • 681
  • 3
  • 15
  • The question is what do you do with `response` in `success: function(response) {`. It contains JavaScript code as text. You have to evaluate it. – jabaa Feb 01 '23 at 13:39
  • is that so? i don't see where he used a jquery ajax. he said his "Fetch()" don't even work. also, the response is just a json variable. I'm not sure what you mean by "javascript code as text" – Emre Bener Feb 01 '23 at 16:25
  • Reread the question: _"The API essentially consists of a script normally ran as such"_. In the first snippet, the OP tries to conditionally load the `https://www.fxblue.com/users/dynascalp_demo/overviewscript`. This script contains a code like `if (!document.MTIntelligenceAccounts) ...` (second code snippet). The OP doesn't try to load data. – jabaa Feb 01 '23 at 18:45
  • it is possible to load a script conditionally using razor, like so; @if (Environment.IsDevelopment()) { } – Emre Bener Feb 10 '23 at 07:37
  • [What is the difference between client-side and server-side programming?](https://stackoverflow.com/questions/13840429/what-is-the-difference-between-client-side-and-server-side-programming) The OP wants a condition in the client-side code, not in the Server-Side code. – jabaa Feb 10 '23 at 08:40