conceptualizing noSQL... using Magic the Gathering - json

So, I've been using SQL for ever. It's all I know, really, but I really want to understand how to conceptualize document data.
{
"MBS":{
"name":"Mirrodin Besieged",
"code":"MBS",
"releaseDate":"2011-02-04",
"border":"black",
"type":"expansion",
"block":"Scars of Mirrodin",
"cards":[
{"layout":"normal",
"type":"Creature — Human Knight",
"types":["Creature"],
"colors":["White"],
"multiverseid":214064,
"name":"Hero of Bladehold",
"subtypes":["Human", "Knight"],
"cmc":4,
"rarity":"Mythic Rare",
"artist":"Austin Hsu",
"power":"3",
"toughness":"4",
"manaCost":"{2}{W}{W}",
"text":"Battle cry (Whenever this creature attacks, each other attacking creature gets +1/+0 until end of turn.)\n\nWhenever Hero of Bladehold attacks, put two 1/1 white Soldier creature tokens onto the battlefield tapped and attacking.",
"number":"8",
"watermark":"Mirran",
"rulings":[
{"date":"2011-06-01", "text":"Whenever Hero of Bladehold attacks, both abilities will trigger. You can put them onto the stack in any order. If the token-creating ability resolves first, the tokens each get +1/+0 until end of turn from the battle cry ability."},
{"date":"2011-06-01", "text":"You choose which opponent or planeswalker an opponent controls that each token is attacking when it is put onto the battlefield."},
{"date":"2011-06-01", "text":"Although the tokens are attacking, they never were declared as attacking creatures (for purposes of abilities that trigger whenever a creature attacks, for example)."}
],
"imageName":"hero of bladehold",
"foreignNames":[
{"language":"Chinese Traditional", "name":"銳鋒城塞勇士"},
{"language":"Chinese Simplified", "name":"锐锋城塞勇士"},
{"language":"French", "name":"Héroïne de Fortcoutel"},
{"language":"German", "name":"Held der Klingenfeste"},
{"language":"Italian", "name":"Eroina di Rifugio delle Lame"},
{"language":"Japanese", "name":"刃砦の英雄"},
{"language":"Portuguese (Brazil)", "name":"Herói de Bladehold"},
{"language":"Russian", "name":"Герой Блэйдхолда"},
{"language":"Spanish", "name":"Héroe de Fortaleza del Filo"}
],
"printings":["Mirrodin Besieged"]},
{next card...},
{next card...},
{next card...},
{last card...}
]
},
{next set...},
{next set...},
{last set...}
}
So, I have a json file of all of the cards from Magic: The Gathering. The json is 'segmented' into the different sets. So, if I were to import this somehow into a noSQL database (mongoDB):
what would constitute a document?
Is each set a document?
Is each card a document?
What would be a good structure?
How does the querying work at that point... is it just a giant 'text search' if I'm looking for something?
Just looking for some sort of insight to wrap my head around noSQL.

Related

Sentence-count function not returning total count

So i've been trying to create a sentence-count function which will cycle through the following 'story':
let story = 'Last weekend, I took literally the most beautiful bike ride of my life. The route is called "The 9W to Nyack" and it actually stretches all the way from Riverside Park in Manhattan to South Nyack, New Jersey. It\'s really an adventure from beginning to end! It is a 48 mile loop and it basically took me an entire day. I stopped at Riverbank State Park to take some extremely artsy photos. It was a short stop, though, because I had a really long way left to go. After a quick photo op at the very popular Little Red Lighthouse, I began my trek across the George Washington Bridge into New Jersey. The GW is actually very long - 4,760 feet! I was already very tired by the time I got to the other side. An hour later, I reached Greenbrook Nature Sanctuary, an extremely beautiful park along the coast of the Hudson. Something that was very surprising to me was that near the end of the route you actually cross back into New York! At this point, you are very close to the end.';
And I realise the problem I'm having but I cannot find a way around this. Basically I want my code to return a the total sCount below but seeing as I've returned my sCount after my loop, it's only adding and returning the one count as a total:
const sentenceTotal = (word) => {
let sCount = 0;
if (word[word.length-1] === "." || word[word.length-1] === "!" || word[word.length-1] === "?") {
sCount += 1;
};
return sCount;
};
// console.log(sentenceTotal(story)) returns '1'.
I've tried multiple ways around this, such as returning sentenceTotal(word) instead of sCount but console.log will just log the function name.
I can make it return the correct sCount total if I remove the function element of it, but that's not what I want.
I don't see any loop or iterator which would go through story to count the number of occurrences of ., ?, or !.
Having recently tackled "counting sentences" myself I know it is a non-trivial problem with many edge cases.
For a simple use-case though you can use split and a regular expression;
story.split(/[?!.]/).length
So you could wrap that in your function like so:
const sentenceTotal = (word) => {
return word.split(/[?.!]/).length
};
let story = 'Last weekend, I took literally the most beautiful bike ride of my life. The route is called "The 9W to Nyack" and it actually stretches all the way from Riverside Park in Manhattan to South Nyack, New Jersey. It\'s really an adventure from beginning to end! It is a 48 mile loop and it basically took me an entire day. I stopped at Riverbank State Park to take some extremely artsy photos. It was a short stop, though, because I had a really long way left to go. After a quick photo op at the very popular Little Red Lighthouse, I began my trek across the George Washington Bridge into New Jersey. The GW is actually very long - 4,760 feet! I was already very tired by the time I got to the other side. An hour later, I reached Greenbrook Nature Sanctuary, an extremely beautiful park along the coast of the Hudson. Something that was very surprising to me was that near the end of the route you actually cross back into New York! At this point, you are very close to the end.';
sentenceTotal(story)
=> 13
There a several strange things about you question so I'll do it in 3 steps :
First step : The syntax.
What you wrote is the assignement to a const of an anonymous variable. So what it does is :
Create a const name 'sentenceCount'
To this const, assign the anonymous function (words) => {...}
Now you have this : sentenceCount(words){...}
And that's all. Because what you wrote : ()=>{} is not the calling of a function, but the declaration of an anonym function, you should read this : https://www.w3schools.com/js/js_function_definition.asp
If you want a global total, you must have a global total variable(not constant) so that the total isn't lost. So :
let sCount = 0; //<-- have sCount as a global variable not a const
function isEndOfSentence(word) {
if (word[word.length-1] === "." || word[word.length-1] === "!" || word[word.length-1] === "?") {
sCount += 1;
};
};
If you are forbidden from using a global variable (and it's best to not do so), then you have to register the total as a return of your function and store the total in the calling 'CountWords(sentence)' function.
function isEndOfSentence(words) {...}
callingFunction(){
//decalaration
let total;
//...inside your loop
total += isEndOfSentence(currentWord)
}
The algorithm
Can you provide more context as how you use you function ?
If your goal is to count the words until there is a delimiter to mark the end of a sentence, your function will not be of great usage .
As it is written, your function will only ever be able to return 0 or 1. As it does the following :
The function is called.
It create a var called sCount and set it to 0
It increment or not sCount
It return sCount so 1 or 0
It's basically a 'isEndOfSentence' function that would return a boolean. It's usage should be in an algorithm like :
// var totalSentence = 0
// for each word
// if(isEndOfSentence(word))
// totalSentence + totalSentence = 1
// endfor
Also this comes back to just counting the punctuation to count the number of sentence.
The quick and small solution
Also I tried specifically to keep the program in an algorithm explicit form since I guess that's what you're dealing with.
But I feel that you wanted to write something small and with as little characters as possible so for your information, there are faster way of doing this with a tool called regex and the native JS 'split(separator)' function of a string.
A regex is a description of a string that it can match to and when used can return those match. And it can be used in JS to split a string:
story.split(/[?!.]/) //<-- will return an array of the sentences of your story.
story.split(/[?!.]/).length //<-- will return the number of element of the array of the sentences of your story, so the sentence count
That does what you wanted but with one line of code. But If you want to be smart about you problem, remember that I said
Also this comes back to just counting the punctuation to count the number of sentence.
So we'll just do that right ?
story.match(/(\.\.\.)|[.?!]/g).length
Have fun here ;) : https://regexr.com/
I hope that helps you ! Good luck !

Convert HTML to PDF in Power Automate

I am working on Power Automate and trying to convert an HTML page into a pdf file. However, before the HTML page content loads completely, the conversion process takes place. As a result, the pdf file created is either blank or has a loading symbol.
I believe the need is to add a manual delay of a few seconds between page load and pdf file conversion, but am unable to do so.
Below is the concerned 'definition' file JSON code extracted after exported the Power Automate Flow. The connector for pdf conversion can be searched as "operationId":"ConvertFileByPath"
{"name":"611652cf-aec0-4733-8871-b0f0f40af783","id":"/providers/Microsoft.Flow/flows/611652cf-aec0-4733-8871-b0f0f40af783","type":"Microsoft.Flow/flows","properties":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_logicflows","displayName":"Enterprise
Assessment Tool","definition":{"metadata":{"workflowEntityId":null,"creator":{"id":"4205125c-5d6f-4e96-b565-709e4a8dcbde","type":"User","tenantId":"971f0e31-00d6-4e42-b8e0-47b342bc4455"},"provisioningMethod":"FromDefinition","failureAlertSubscription":true,"clientLastModifiedTime":"2020-03-20T08:55:47.5792257Z"},"$schema":"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#","contentVersion":"1.0.0.0","parameters":{"$connections":{"defaultValue":{},"type":"Object"},"$authentication":{"defaultValue":{},"type":"SecureObject"}},"triggers":{"When_a_new_response_is_submitted":{"type":"OpenApiConnectionWebhook","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_microsoftforms","connectionName":"shared_microsoftforms_2","operationId":"CreateFormWebhook"},"parameters":{"form_id":"MQ4fl9YAQk644EezQrxEVVwSBUJvXZZOtWVwnkqNy95UNkVCVlJZSVlHQlBEWFhOMkFJUE5PT1pSWS4u"},"authentication":"#parameters('$authentication')"}}},"actions":{"Apply_to_each":{"foreach":"#triggerOutputs()?['body/value']","actions":{"Get_response_details":{"runAfter":{},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_microsoftforms","connectionName":"shared_microsoftforms_2","operationId":"GetFormResponseById"},"parameters":{"form_id":"MQ4fl9YAQk644EezQrxEVVwSBUJvXZZOtWVwnkqNy95UNkVCVlJZSVlHQlBEWFhOMkFJUE5PT1pSWS4u","response_id":"#items('Apply_to_each')?['resourceData/responseId']"},"authentication":"#parameters('$authentication')"}},"Add_a_row_into_a_table":{"runAfter":{"Get_response_details":["Succeeded"]},"metadata":{"016AIIWUWO74RBMREYLVAIQPOYYNXRWO3P":"/Enterprise
Assessment Tool.xlsx","tableId":"{9C186D95-CBB6-477E-8699-17B3089A0368}","01BSP3ENPNPETDO5YJUVBI2X6MEG5ARSKV":"/Enterprise Assessment Tool.xlsx"},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_excelonlinebusiness","connectionName":"shared_excelonlinebusiness_1","operationId":"AddRowV2"},"parameters":{"source":"me","drive":"b!wjpSLG6KfES6F9-MfcSm-aeq5llhoTVMpfXuBQBmrywjSt-PswuwSbm1_6BG5sFo","file":"01BSP3ENPNPETDO5YJUVBI2X6MEG5ARSKV","table":"{9C186D95-CBB6-477E-8699-17B3089A0368}","item/ID":"#items('Apply_to_each')?['resourceData/responseId']","item/Your
name":"#outputs('Get_response_details')?['body/r6b6a573a836044eab553ba2e0ab92446']","item/Organization’s Name":"#outputs('Get_response_details')?['body/ra2af29025bff44bbac289f9c61c76666']","item/Your Email Address":"#outputs('Get_response_details')?['body/rf505d38dc6334aa7b69d2c77f230f09e']","item/Providing
clear and effective leadership":"#outputs('Get_response_details')?['body/r4b5eade301884d9b8629c9b38d9a3c2d']","item/Anticipating opportunities and threats to keep us ahead of change":"#outputs('Get_response_details')?['body/rca90ae117bc347f9886072f118ceb630']","item/Willingness
to take on risks for long-term growth, even if that could decrease current year profits":"#outputs('Get_response_details')?['body/rc8656608760f4e19abc1d78ecacbf825']","item/Making disciplined IT investment decisions":"#outputs('Get_response_details')?['body/r14226cb30f604f20a626157ec1786086']","item/Using
IT to gain competitive advantage":"#outputs('Get_response_details')?['body/r963c2865db4d4e90b20fa82547a48c62']","item/Articulating a clear and consistent vision to employees, consumers and partners":"#outputs('Get_response_details')?['body/r01698107f2ea4286a8f59ec20f17f3b8']","item/Enabling
the enterprise to navigate change":"#outputs('Get_response_details')?['body/r2c02b757c2444656a4c32388e2353724']","item/Fostering and changing the culture in IT":"#outputs('Get_response_details')?['body/r09d450406bfb477bb55cfd5dd572eb09']","item/Please
rate the clarity and consistency of your enterprise’s overall business strategy_x002e_":"#outputs('Get_response_details')?['body/r5bdc0ce9ba0b46348149fb2422b4e041']","item/Please indicate the nature of your organization’s CIO’s (or the most senior IT
leader’s) relationship with the CEO (or most senior Business executive)_x002e_":"#outputs('Get_response_details')?['body/r29c1767ce4bd4da6bec697ede635a908']","item/Has your organization faced any of these situations in the past four years? Please select
all that apply_x002e_":"#outputs('Get_response_details')?['body/rb4f8047c739d42938a52145e9a9cbef1']","item/Please share some details regarding the business disruption that you faced in the past four years_x002e_":"#outputs('Get_response_details')?['body/r7652d524e6524ba19fe6c629c4869aa0']","item/External
disruption of your business environment":"#outputs('Get_response_details')?['body/rd3d4bb9074a2411d9234551e0092500c']","item/Adverse regulatory intervention":"#outputs('Get_response_details')?['body/rc01f99fd45e74f5695e7fbcbcd66b6a4']","item/Cyber security
issue":"#outputs('Get_response_details')?['body/reb816f5b028b43ccb22128f0bac6bc00']","item/IT Service failure":"#outputs('Get_response_details')?['body/r95c7899a06e74c04b6a4f96fb905abe8']","item/Product~1service failure":"#outputs('Get_response_details')?['body/r15ea7200480b45febe0384a5ad4fe683']","item/Operating
cost pressure":"#outputs('Get_response_details')?['body/r952f66721ebf48b6bb9e23f64273ae6a']","item/Labor disruption":"#outputs('Get_response_details')?['body/ree57c3756cc04cf8b0d37e158256b1ef']","item/Shifting consumer demand":"#outputs('Get_response_details')?['body/r712b33b666694e80be27b2bcfb4bba86']","item/Funding
shortfall":"#outputs('Get_response_details')?['body/r493be3af3d244d638863da8b4e68fadc']","item/Organizational disruption":"#outputs('Get_response_details')?['body/r90bcccc8a1c3475186f5454677e9199a']","item/Some other disruptive business situation":"#outputs('Get_response_details')?['body/r939f57c83c054ab08d6c64c33bb5c62b']","item/The
overall business performance of the enterprise":"#outputs('Get_response_details')?['body/r729caa64609d4b998cfd200997bdca41']","item/Speed at which new business initiatives are launched":"#outputs('Get_response_details')?['body/r3061360c935d4f0093939e6b64bec6b7']","item/Ability
to fund new business initiatives":"#outputs('Get_response_details')?['body/rb186360b5d6a455d8ed624c1ab6a8ac0']","item/Speed at which business initiatives are successfully completed":"#outputs('Get_response_details')?['body/r3061360c935d4f0093939e6b64bec6b7']","item/Ability
to use data to achieve intended outcomes":"#outputs('Get_response_details')?['body/r2f1fc86f6d6f4cf6a78528bdf5b8e7e2']","item/Ability to attract the right talent to fill our needs":"#outputs('Get_response_details')?['body/rc3a23d40f20f49b78cab3880f0c8db38']","item/Ability
to get value from new business initiatives":"#outputs('Get_response_details')?['body/r4e4371bf1cdc472c8935bc398f7751b5']","item/IT budget growth":"#outputs('Get_response_details')?['body/rc0a78909625144acbc4d9d94658b0c74']","item/Operating cost competitiveness":"#outputs('Get_response_details')?['body/rac841e5b9e064ee88ec84dd54f48e40e']","item/Reputation
as an innovative enterprise":"#outputs('Get_response_details')?['body/r5ebbb6aebc8e4623bf987dca1e01afd1']","item/Our long-term viability":"#outputs('Get_response_details')?['body/rb83eaa31847f4306a54fa6375d5d544d']","item/The stability of the leadership
team (CEO and downward)":"#outputs('Get_response_details')?['body/r7ac35c66284e4215b4dd6ac173134b54']"},"authentication":"#parameters('$authentication')"}}},"runAfter":{},"type":"Foreach"},"Refresh_a_dataset":{"runAfter":{"Delay_2":["Succeeded"]},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_powerbi","connectionName":"shared_powerbi","operationId":"RefreshDataset"},"parameters":{"groupid":"42cf205d-726b-418a-b227-d03cbcaa9f6b","datasetid":"36269b8f-45cd-43c7-a2fa-a3995da63c51"},"authentication":"#parameters('$authentication')"}},"Delay":{"runAfter":{"Refresh_a_dataset":["Succeeded"]},"type":"Wait","inputs":{"interval":{"count":1,"unit":"Minute"}}},"Delay_2":{"runAfter":{"Apply_to_each":["Succeeded"]},"type":"Wait","inputs":{"interval":{"count":1,"unit":"Minute"}}},"Apply_to_each_3":{"foreach":"#triggerOutputs()?['body/value']","actions":{"Get_response_details_3":{"runAfter":{},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_microsoftforms","connectionName":"shared_microsoftforms_2","operationId":"GetFormResponseById"},"parameters":{"form_id":"MQ4fl9YAQk644EezQrxEVVwSBUJvXZZOtWVwnkqNy95UNkVCVlJZSVlHQlBEWFhOMkFJUE5PT1pSWS4u","response_id":"#items('Apply_to_each_3')?['resourceData/responseId']"},"authentication":"#parameters('$authentication')"}},"Convert_HTML_to_PDF":{"runAfter":{"Get_response_details_3":["Succeeded"]},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_encodiandocumentmanager","connectionName":"shared_encodiandocumentmanager","operationId":"HtmlToPDF"},"parameters":{"operation/outputFilename":"Enterprise
Fitness Assessment Report_#{outputs('Get_response_details_3')?['body/ra2af29025bff44bbac289f9c61c76666']}","operation/htmlData":"
<!DOCTYPE html>\n
<html>\n\n
<head>\n
<script>
\
n\ nwindow.addEventListener('load', function() {\
nsetInterval(function() {\
ndocument.getElementById(\"delayedText\").style.visibility = \"visible\";\n},10000);\n\n}, false);\n\n/*window.onload = function(){\n \n var theDelay = 60;\n var timer = setTimeout(\"showText()\",theDelay*1000)\n}\nfunction showText(){\n document.getElementById(\"delayedText\").style.visibility = \"visible\";\n}*/\n\n\n
</script>\n</head>\n\n
<body>\n
<div id=\ "delayedText\" style=\ "visibility:hidden\">This is a test\n\n<iframe width=\ "1140\" height=\ "541.25\" src=\
"https://app.powerbi.com/reportEmbed?reportId=d27f0160-eb09-442b-a7ab-ded938ed33ec&autoAuth=true&ctid=971f0e31-00d6-4e42-b8e0-47b342bc4455&config=eyJjbHVzdGVyVXJsIjoiaHR0cHM6Ly93YWJpLXdlc3QtdXMtcmVkaXJlY3QuYW5hbHlzaXMud2luZG93cy5uZXQvIn0%3D\" frameborder=\ "0\" allowFullScreen=\ "true\"></iframe>\n</div>\n\n</body>\n
</html>","operation/pageOrientation":"Landscape","operation/pageSize":"A4","operation/viewPort":"Default","operation/MarginTop":25,"operation/MarginBottom":25,"operation/MarginRight":25,"operation/MarginLeft":25,"operation/enableBookmarks":true,"operation/enableJavaScript":true,"operation/enableHyperlinks":true,"operation/createPdfForm":false,"operation/decodeHtmlData":true,"operation/cssType":"Screen","operation/repeatTableHeader":true,"operation/repeatTableFooter":true,"operation/splitImages":false,"operation/splitTextLines":false,"operation/encoding":"UTF8","operation/FinalOperation":true},"authentication":"#parameters('$authentication')"}},"Create_file":{"runAfter":{"Convert_HTML_to_PDF":["Succeeded"]},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness","connectionName":"shared_onedriveforbusiness","operationId":"CreateFile"},"parameters":{"folderPath":"/Enterprise
Assessment Reports","name":"#outputs('Convert_HTML_to_PDF')?['body/Filename']","body":"#outputs('Convert_HTML_to_PDF')?['body/FileContent']"},"authentication":"#parameters('$authentication')"},"runtimeConfiguration":{"contentTransfer":{"transferMode":"Chunked"}}},"Send_an_email":{"runAfter":{"Create_file":["Succeeded"]},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_office365","connectionName":"shared_office365","operationId":"SendEmailV2"},"parameters":{"emailMessage/To":"#outputs('Get_response_details_3')?['body/rf505d38dc6334aa7b69d2c77f230f09e']","emailMessage/Subject":"Gartner
Enterprise Fitness Assessment Report","emailMessage/Body":"
<p>Hi #{outputs('Get_response_details_3')?['body/r6b6a573a836044eab553ba2e0ab92446']}<br>\n<br>\nThanks for submitting your response! Please view the attachement for your organisation's assessment.<br>\n<br>\nTeam PRM</p>","emailMessage/From":"Prakhar.Gupta#gartner.com","emailMessage/Attachments":[{"Name":"#outputs('Convert_HTML_to_PDF')?['body/Filename']","ContentBytes":"#outputs('Convert_HTML_to_PDF')?['body/FileContent']"}]},"authentication":"#parameters('$authentication')"}}},"runAfter":{"Send_an_email_(V2)":["Succeeded"]},"type":"Foreach"},"Send_an_email_(V2)":{"runAfter":{"Create_file_3":["Succeeded"]},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_office365","connectionName":"shared_office365","operationId":"SendEmailV2"},"parameters":{"emailMessage/To":"Prakhar.Gupta#gartner.com","emailMessage/Subject":"test","emailMessage/Body":"
<!DOCTYPE html>\n
<html>\n\n
<head>\n
<script>
\
n\ nwindow.addEventListener('load', function() {\
nsetInterval(function() {\
ndocument.getElementById(\"delayedText\").style.visibility = \"visible\";\n},10000);\n\n}, false);\n\n/*window.onload = function(){\n \n var theDelay = 60;\n var timer = setTimeout(\"showText()\",theDelay*1000)\n}\nfunction showText(){\n document.getElementById(\"delayedText\").style.visibility = \"visible\";\n}*/\n\n\n
</script>\n</head>\n\n
<body>\n
<div id=\ "delayedText\" style=\ "visibility:hidden\">This is a test\n\n<iframe width=\ "1140\" height=\ "541.25\" src=\
"https://app.powerbi.com/reportEmbed?reportId=d27f0160-eb09-442b-a7ab-ded938ed33ec&autoAuth=true&ctid=971f0e31-00d6-4e42-b8e0-47b342bc4455&config=eyJjbHVzdGVyVXJsIjoiaHR0cHM6Ly93YWJpLXdlc3QtdXMtcmVkaXJlY3QuYW5hbHlzaXMud2luZG93cy5uZXQvIn0%3D\" frameborder=\ "0\" allowFullScreen=\ "true\"></iframe>\n</div>\n\n</body>\n
</html>"},"authentication":"#parameters('$authentication')"}},"Create_file_2":{"runAfter":{"Delay":["Succeeded"]},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness","connectionName":"shared_onedriveforbusiness","operationId":"CreateFile"},"parameters":{"folderPath":"/Enterprise
Assessment Reports","name":"Test.html","body":"
<!DOCTYPE html>\n
<html>\n\n
<head>\n
<script>
\
n\ nwindow.addEventListener('load', function() {\
nsetInterval(function() {\
ndocument.getElementById(\"delayedText\").style.visibility = \"visible\";\n},10000);\n\n}, false);\n\n/*window.onload = function(){\n \n var theDelay = 60;\n var timer = setTimeout(\"showText()\",theDelay*1000)\n}\nfunction showText(){\n document.getElementById(\"delayedText\").style.visibility = \"visible\";\n}*/\n\n\n
</script>\n</head>\n\n
<body>\n
<div id=\ "delayedText\" style=\ "visibility:hidden\">This is a test\n\n<iframe width=\ "1140\" height=\ "541.25\" src=\
"https://app.powerbi.com/reportEmbed?reportId=d27f0160-eb09-442b-a7ab-ded938ed33ec&autoAuth=true&ctid=971f0e31-00d6-4e42-b8e0-47b342bc4455&config=eyJjbHVzdGVyVXJsIjoiaHR0cHM6Ly93YWJpLXdlc3QtdXMtcmVkaXJlY3QuYW5hbHlzaXMud2luZG93cy5uZXQvIn0%3D\" frameborder=\ "0\" allowFullScreen=\ "true\"></iframe>\n</div>\n\n</body>\n
</html>"},"authentication":"#parameters('$authentication')"},"runtimeConfiguration":{"contentTransfer":{"transferMode":"Chunked"}}},"Delay_3":{"runAfter":{"Create_file_2":["Succeeded"]},"type":"Wait","inputs":{"interval":{"count":3,"unit":"Minute"}}},"Convert_file_using_path":{"runAfter":{"Delay_3":["Succeeded"]},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness","connectionName":"shared_onedriveforbusiness","operationId":"ConvertFileByPath"},"parameters":{"path":"#outputs('Create_file_2')?['body/Path']","type":"PDF"},"authentication":"#parameters('$authentication')"}},"Create_file_3":{"runAfter":{"Convert_file_using_path":["Succeeded"]},"type":"OpenApiConnection","inputs":{"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness","connectionName":"shared_onedriveforbusiness","operationId":"CreateFile"},"parameters":{"folderPath":"/Enterprise
Assessment Reports","name":"#outputs('Convert_file_using_path')?['headers/x-ms-file-name']","body":"#outputs('Convert_file_using_path')?['body']"},"authentication":"#parameters('$authentication')"},"runtimeConfiguration":{"contentTransfer":{"transferMode":"Chunked"}}}},"outputs":{},"description":"Track
Microsoft Forms responses in an Excel Online (Business) spreadsheet. The spreadsheet must have columns: SubmissionTime, ResponderEmail."},"connectionReferences":{"shared_microsoftforms_2":{"connectionName":"shared-microsoftform-ff875ca3-62f2-4c71-bed9-8d02ce26ada2","source":"Embedded","id":"/providers/Microsoft.PowerApps/apis/shared_microsoftforms","tier":"NotSpecified"},"shared_excelonlinebusiness_1":{"connectionName":"shared-excelonlinebu-aabd11c2-e15f-4595-a539-d4ffe5ecd544","source":"Embedded","id":"/providers/Microsoft.PowerApps/apis/shared_excelonlinebusiness","tier":"NotSpecified"},"shared_powerbi":{"connectionName":"shared-powerbi-07a589e5-e541-4241-83c7-2e5ba184ec9f","source":"Embedded","id":"/providers/Microsoft.PowerApps/apis/shared_powerbi","tier":"NotSpecified"},"shared_encodiandocumentmanager":{"connectionName":"shared-encodiandocum-29f09c50-052b-4d59-8c60-7876ab0cf806","source":"Embedded","id":"/providers/Microsoft.PowerApps/apis/shared_encodiandocumentmanager","tier":"NotSpecified"},"shared_onedriveforbusiness":{"connectionName":"shared-onedriveforbu-2262692c-87ba-4be3-a32d-febd64f70219","source":"Embedded","id":"/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness","tier":"NotSpecified"},"shared_office365":{"connectionName":"shared-office365-28369e56-7ed4-431e-9b7b-ba4930b0f010","source":"Embedded","id":"/providers/Microsoft.PowerApps/apis/shared_office365","tier":"NotSpecified"}},"flowFailureAlertSubscribed":false}}
You can use the Run after property on the action to get the HTML.
So once the action return then you convert your PDF

why i cannot read json data by using keys instead of indexes angular 2?

I am currently working in angular 2 and receiving my json data through api. i received that data in following format.
{
"totalItems": 2719,
"totalPages": 272,
"results": [
{
"SNR_Title": "Acer - 11 11.6\" Refurbished Chromebook - Intel Celeron - 4GB Memory - 16GB eMMC Flash Memory - Gray",
"SNR_Brand": "Acer",
"SNR_Description": "Refurbished Acer 11 Chromebook: Slip the Acer Chromebook into your bag and work from anywhere, without recharging, because it has enough battery life to last for a long time on a single charge. Learn more about refurbished products › Learn more about Chromebooks ›",
"SNR_ImageURL": "https://img.bbystatic.com/BestBuy_US/images/products/5676/5676707_sa.jpg",
"SNR_ModelNo": "NX.GC1AA.002",
"SNR_UPC": "841631108389",
"SNR_SKU": "5676707",
"SNR_ProductURL": "https://api.bestbuy.com/click/-/5676707/pdp",
"SNR_Price": "169.99",
"SNR_Available": "BESTBUY"
},
{
"SNR_Title": "Acer - 11.6\" Chromebook - Intel Celeron - 2GB Memory - 16GB eMMC Flash Memory - White",
"SNR_Brand": "Acer",
"SNR_Description": "Acer Chromebook: Browse the Internet and tackle work or school projects with this Acer Chromebook. An 11.6-inch LED backlit display and an Intel HD graphics card provide a rich viewing experience for images and video, and a built-in webcam lets you place video calls with crisp clarity. With its compact size and 9-hour battery life, this Acer Chromebook is ideal for travel. Learn more about Chromebooks ›",
"SNR_ImageURL": "https://img.bbystatic.com/BestBuy_US/images/products/4963/4963801_sa.jpg",
"SNR_ModelNo": "CB3131C3SZ",
"SNR_UPC": "888863408634",
"SNR_SKU": "4963801",
"SNR_ProductURL": "https://api.bestbuy.com/click/-/4963801/pdp",
"SNR_Price": "179.0",
"SNR_Available": "BESTBUY"
}
]
}
and my service or .ts class where i am receiving this look like this.
GetAllMobile:Object
constructor(private httpService: HttpService) {
this.httpService.getAllMobiles(1).subscribe(
data => {
const myArray = [];
for (let key in data) {
myArray.push(data[key]);
// console.log(this.GetAllMobile)
}
this.GetAllMobile=(myArray)
}
);
but i cannot read GetAllMobile.results in my html but i can access it by using index like GetAllMobile[2].
what i have tried so far is following.
//Not worked
<div *ngFor="let item of GetAllMobile">
<h2>
Total {{item.totalItems}} {{item.totalPages}} AMAD
</h2>
<div *ngFor="let x of item.results">
<p>
{{x.SNR_Title}}
</p>
</div>
</div>
//this woked but i don't needed this approach
<div *ngFor="let mobile of GetAllMobile[2]">
<h2>{{ mobile.SNR_Title}}</h2>
</div>
but i can read by using indexes. but for some reasons i want to read data by key. can some body tell me what is right approach to read this data in angular 2.
any help or suggestions are highly appreciated.
You are trying to over complicate things a bit :)
You can just assign the response you are getting as is, no need to try and loop it. So just do:
this.httpService.getAllMobiles(1).subscribe(data => {
this.GetAllMobiles = data;
})
Then your template would look like the following. Notice that we are removing the first iteration, since there is nothing to iterate. GetAllMobile is an object. The second iteration we keep, as you want to iterate the results array that is inside your object.
<h2>Total {{GetAllMobile?.totalItems}} {{GetAllMobile?.totalPages}} AMAD</h2>
<div *ngFor="let x of GetAllMobile?.results">
<p>{{x.SNR_Title}}</p>
</div>
Notice the use of safe navigation operator. It safeguards null and undefined property paths. Since data is coming asyncronously it is good to use the safe nav operator. In this case this can also be solved by just initializing the variable GetAllMobile, but it's useful to know about the safe nav operator in the magical asynchronous world :)
Finally, here's a DEMO
try to declare GetAllMobile like this :
GetAllMobile : Array<{totalItems: String, totalPages: string,results: Array<any>}>;
hope this will helps you :)

Not getting display as a list from json file

I am new to ionic framework and I had stuck in the following issue :
data.json:
{ "speakers" : [
{
"name":"Mr Bellingham",
"shortname":"Barot_Bellingham",
"reknown":"Royal Academy of Painting and Sculpture",
"bio":"Barot has just finished his final year at The Royal Academy of Painting and Sculpture, where he excelled in glass etching paintings and portraiture. Hailed as one of the most diverse artists of his generation, Barot is equally as skilled with watercolors as he is with oils, and is just as well-balanced in different subject areas. Barot's collection entitled \"The Un-Collection\" will adorn the walls of Gilbert Hall, depicting his range of skills and sensibilities - all of them, uniquely Barot, yet undeniably different"
},
{
"name":"Jonathan G. Ferrar II",
"shortname":"Jonathan_Ferrar",
"reknown":"Artist to Watch in 2012",
"bio":"The Artist to Watch in 2012 by the London Review, Johnathan has already sold one of the highest priced-commissions paid to an art student, ever on record. The piece, entitled Gratitude Resort, a work in oil and mixed media, was sold for $750,000 and Jonathan donated all the proceeds to Art for Peace, an organization that provides college art scholarships for creative children in developing nations"
},
{
"name":"Hillary Hewitt Goldwynn-Post",
"shortname":"Hillary_Goldwynn",
"reknown":"New York University",
"bio":"Hillary is a sophomore art sculpture student at New York University, and has already won all the major international prizes for new sculptors, including the Divinity Circle, the International Sculptor's Medal, and the Academy of Paris Award. Hillary's CAC exhibit features 25 abstract watercolor paintings that contain only water images including waves, deep sea, and river."
},
{
"name":"Hassum Harrod",
"shortname":"Hassum_Harrod",
"reknown":"Art College in New Dehli",
"bio":"The Art College in New Dehli has sponsored Hassum on scholarship for his entire undergraduate career at the university, seeing great promise in his contemporary paintings of landscapes - that use equal parts muted and vibrant tones, and are almost a contradiction in art. Hassum will be speaking on \"The use and absence of color in modern art\" during Thursday's agenda."
},
{
"name":"Jennifer Jerome",
"shortname":"Jennifer_Jerome",
"reknown":"New Orleans, LA",
"bio":"A native of New Orleans, much of Jennifer's work has centered around abstract images that depict flooding and rebuilding, having grown up as a teenager in the post-flood years. Despite the sadness of devastation and lives lost, Jennifer's work also depicts the hope and togetherness of a community that has persevered. Jennifer's exhibit will be discussed during Tuesday's Water in Art theme."
},
{
"name":"LaVonne L. LaRue",
"shortname":"LaVonne_LaRue",
"reknown":"Chicago, IL",
"bio":"LaVonne's giant-sized paintings all around Chicago tell the story of love, nature, and conservation - themes that are central to her heart. LaVonne will share her love and skill of graffiti art on Monday's schedule, as she starts the painting of a 20-foot high wall in the Rousseau Room of Hotel Contempo in front of a standing-room only audience in Art in Unexpected Places."
},
{
"name":"Constance Olivia Smith",
"shortname":"Constance_Smith",
"reknown":"Fullerton-Brighton-Norwell Award",
"bio":"Constance received the Fullerton-Brighton-Norwell Award for Modern Art for her mixed-media image of a tree of life, with jewel-adorned branches depicting the arms of humanity, and precious gemstone-decorated leaves representing the spouting buds of togetherness. The daughter of a New York jeweler, Constance has been salvaging the discarded remnants of her father's jewelry-making since she was five years old, and won the New York State Fair grand prize at the age of 8 years old for a gem-adorned painting of the Manhattan Bridge."
},
{
"name":"Riley Rudolph Rewington",
"shortname":"Riley_Rewington",
"reknown":"Roux Academy of Art, Media, and Design",
"bio":"A first-year student at the Roux Academy of Art, Media, and Design, Riley is already changing the face of modern art at the university. Riley's exquisite abstract pieces have no intention of ever being understood, but instead beg the viewer to dream, create, pretend, and envision with their mind's eye. Riley will be speaking on the \"Art of Abstract\" during Thursday's schedule"
},
{
"name":"Xhou Ta",
"shortname":"Xhou_Ta",
"reknown":"China International Art University",
"bio":"A senior at the China International Art University, Xhou has become well-known for his miniature sculptures, often the size of a rice granule, that are displayed by rear projection of microscope images on canvas. Xhou will discuss the art and science behind his incredibly detailed works of art."
}
]}
app.js :
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.controller('ListController', ['$scope','$http',function($scope,$http){
$http.get('js/data.json').success(function(data){
$scope.artists = data;
});
}])
index.html :
<ion-content ng-controller="ListController" class="has-subheader">
<ion-list>
<ion-item ng-repeat='item in artists' class="item-thumbnail-left item-text-wrap">
<img src="img/{{item.shortname}}_tn.jpg">
<h2>{{item.shortname}}</h2>
<h3>{{item.reknown}}</h3>
<p>
{{item.bio}}
</p>
</ion-item>
</ion-list>
</ion-content>
As you all can see I am trying to list down the data from data.json file but it does not display any data. On console-Network tab I am able to see it call to data.json file but in html it is unable to display. What I am doing wrong? Please help me on this, thanks in advance
Try like this
ng-repeat='item in artists.speakers'
instead of
ng-repeat='item in artists'

Difficulty unpacking JSON tuple string

I figured out how to use rebar. I'm trying to use jsx (jiffy doesn't work properly on Windows) to parse json that I obtained using the openexchangerates.org API, but I can't even figure out how to correctly utilize Erlang's extensive binary functionality in order to unpack the JSON tuple obtained. Using the following code snippet, I managed to get a tuple that has all the data I need:
-module(currency).
-export([start/0]).
start() ->
URL = "http://openexchangerates.org",
Endpoint = "/api/latest.json?app_id=<myprivateid>",
X = string:concat(URL, Endpoint),
% io:format("~p~n",[X]).
inets:start(),
{ok, Req} = httpc:request(X),
Req.
Here is the obtained response:
9> currency:start().
{{"HTTP/1.1",200,"OK"},
[{"cache-control","public"},
{"connection","close"},
{"date","Fri, 15 Aug 2014 01:28:06 GMT"},
{"etag","\"d9ad180d4af1caaedab6e622ec0a8a70\""},
{"server","Apache"},
{"content-length","4370"},
{"content-type","application/json; charset=utf-8"},
{"last-modified","Fri, 15 Aug 2014 01:00:56 GMT"},
{"access-control-allow-origin","*"}],
"{\n \"disclaimer\": \"Exchange rates are provided for informational purposes only, and do not constitute financial advice of any kind. Although every attempt is made to ensure quality, NO guarantees are given whatsoever of accuracy, validity, availability, or fitness for any purpose - please use at your own risk. All usage is subject to your acceptance of the Terms and Conditions of Service, available at: https://openexchangerates.org/terms/\",\n \"license\": \"Data sourced from various providers with public-facing APIs; copyright may apply; resale is prohibited; no warranties given of any kind. Bitcoin data provided by http://coindesk.com. All usage is subject to your acceptance of the License Agreement available at: https://openexchangerates.org/license/\",\n \"timestamp\": 1408064456,\n \"base\": \"USD\",\n \"rates\": {\n \"AED\": 3.673128,\n \"AFN\": 56.479925,\n \"ALL\": 104.147599,\n \"AMD\": 413.859001,\n \"ANG\": 1.789,\n \"AOA\": 97.913074,\n \"ARS\": 8.274908,\n \"AUD\": 1.073302,\n \"AWG\": 1.79005,\n \"AZN\": 0.783933,\n \"BAM\": 1.46437,\n \"BBD\": 2,\n \"BDT\": 77.478631,\n \"BGN\": 1.464338,\n \"BHD\": 0.377041,\n \"BIF\": 1546.956667,\n \"BMD\": 1,\n \"BND\": 1.247024,\n \"BOB\": 6.91391,\n \"BRL\": 2.269422,\n \"BSD\": 1,\n \"BTC\": 0.0019571961,\n \"BTN\": 60.843812,\n \"BWP\": 8.833083,\n \"BYR\": 10385.016667,\n \"BZD\": 1.99597,\n \"CAD\": 1.0906,\n \"CDF\": 924.311667,\n \"CHF\": 0.906799,\n \"CLF\": 0.02399,\n \"CLP\": 577.521099,\n \"CNY\": 6.153677,\n \"COP\": 1880.690016,\n \"CRC\": 540.082202,\n \"CUP\": 1.000688,\n \"CVE\": 82.102201,\n \"CZK\": 20.81766,\n \"DJF\": 178.76812,\n \"DKK\": 5.579046,\n \"DOP\": 43.43789,\n \"DZD\": 79.8973,\n \"EEK\": 11.70595,\n \"EGP\": 7.151305,\n \"ERN\": 15.062575,\n \"ETB\": 19.83205,\n \"EUR\": 0.748385,\n \"FJD\": 1.85028,\n \"FKP\": 0.599315,\n \"GBP\": 0.599315,\n \"GEL\": 1.74167,\n \"GGP\": 0.599315,\n \"GHS\": 3.735499,\n \"GIP\": 0.599315,\n \"GMD\": 39.73668,\n \"GNF\": 6995.309935,\n \"GTQ\": 7.839405,\n \"GYD\": 205.351249,\n \"HKD\": 7.750863,\n \"HNL\": 21.04854,\n \"HRK\": 5.708371,\n \"HTG\": 44.66625,\n \"HUF\": 233.847801,\n \"IDR\": 11682.083333,\n \"ILS\": 3.471749,\n \"IMP\": 0.599315,\n \"INR\": 60.81923,\n \"IQD\": 1178.211753,\n \"IRR\": 26354,\n \"ISK\": 115.976,\n \"JEP\": 0.599315,\n \"JMD\": 112.604801,\n \"JOD\": 0.707578,\n \"JPY\": 102.501401,\n \"KES\": 88.106539,\n \"KGS\": 51.96,\n \"KHR\": 4056.578416,\n \"KMF\": 368.149,\n \"KPW\": 900,\n \"KRW\": 1021.166657,\n \"KWD\": 0.283537,\n \"KYD\": 0.826373,\n \"KZT\": 182.076001,\n \"LAK\": 8049.834935,\n \"LBP\": 1509.068333,\n \"LKR\": 130.184301,\n \"LRD\": 91.49085,\n \"LSL\": 10.56165,\n \"LTL\": 2.583284,\n \"LVL\": 0.521303,\n \"LYD\": 1.244127,\n \"MAD\": 8.372529,\n \"MDL\": 13.7178,\n \"MGA\": 2495.605,\n \"MKD\": 45.99967,\n \"MMK\": 972.1784,\n \"MNT\": 1884.666667,\n \"MOP\": 7.986251,\n \"MRO\": 292.0081,\n \"MTL\": 0.683602,\n \"MUR\": 30.61708,\n \"MVR\": 15.37833,\n \"MWK\": 392.9201,\n \"MXN\": 13.07888,\n \"MYR\": 3.175156,\n \"MZN\": 30.3522,\n \"NAD\": 10.56145,\n \"NGN\": 162.303701,\n \"NIO\": 26.07651,\n \"NOK\": 6.157432,\n \"NPR\": 97.66846,\n \"NZD\": 1.179688,\n \"OMR\": 0.38501,\n \"PAB\": 1,\n \"PEN\": 2.795018,\n \"PGK\": 2.464545,\n \"PHP\": 43.66429,\n \"PKR\": 99.5662,\n \"PLN\": 3.126223,\n \"PYG\": 4272.421673,\n \"QAR\": 3.641137,\n \"RON\": 3.320192,\n \"RSD\": 87.82784,\n \"RUB\": 36.00216,\n \"RWF\": 690.269,\n \"SAR\": 3.750523,\n \"SBD\": 7.269337,\n \"SCR\": 12.40801,\n \"SDG\": 5.699103,\n \"SEK\": 6.86018,\n \"SGD\": 1.246263,\n \"SHP\": 0.599315,\n \"SLL\": 4372.166667,\n \"SOS\": 841.5678,\n \"SRD\": 3.275,\n \"STD\": 18316.816667,\n \"SVC\": 8.745567,\n \"SYP\": 150.751249,\n \"SZL\": 10.56279,\n \"THB\": 31.86192,\n \"TJS\": 4.9856,\n \"TMT\": 2.8501,\n \"TND\": 1.719658,\n \"TOP\": 1.8861,\n \"TRY\": 2.15338,\n \"TTD\": 6.343484,\n \"TWD\": 30.00481,\n \"TZS\": 1661.865,\n \"UAH\": 13.02466,\n \"UGX\": 2614.28,\n \"USD\": 1,\n \"UYU\": 23.70693,\n \"UZS\": 2337.106637,\n \"VEF\": 6.295009,\n \"VND\": 21191.15,\n \"VUV\": 94.6,\n \"WST\": 2.301222,\n \"XAF\": 491.286739,\n \"XAG\": 0.05031657,\n \"XAU\": 0.00076203,\n \"XCD\": 2.70154,\n \"XDR\": 0.654135,\n \"XOF\": 491.394602,\n \"XPF\": 89.414091,\n \"YER\": 214.985901,\n \"ZAR\": 10.55678,\n \"ZMK\": 5253.075255,\n \"ZMW\": 6.169833,\n \"ZWL\": 322.355006\n }\n}"}
I don't understand why this code oesn't work:
X = "Arthur".
B = <<X>>.
JSX allows a lot of parsing functionality but only if I have a binary as my representation of JSON, and this JSON I'm getting from the currency API is a string in a tuple... I'm a bit lost as to where to start to research. Unpacking a tuple using pattern matching is supposedly quite simple (I've done some Prolog programming and I can see that erlang has similar behavior) but is there a another, better, Erlang-appropriate way to grab the "rates" part of the JSON I'm receiving as a response?
Thank you! I'm working on a cool web app to learn erlang and this is a good first step. I have three Erlang books and I'm reading through them diligently but the problem is that I want as much practical exposure as early on as possible. I love this language but I want to get a solid grounding as fast as possible.
Thank you!
get_currencies() ->
URL = "http://openexchangerates.org",
Endpoint = "/api/latest.json?app_id=<myprivateid>",
X = string:concat(URL, Endpoint),
% io:format("~p~n",[X]).
inets:start(),
{ok, {_,_,R}} = httpc:request(X),
E = jsx:decode(lists_to_binary(R)),
Base = proplists:get_value(<<"base">>,E),
Sec = proplists:get_value(<<"timestamp">>,E),
{Days,Time} = calendar:seconds_to_daystime(Sec),
Date = calendar:gregorian_days_to_date(Days+719528),
Currencies = proplists:get_value(<<"rates">>,E),
fun(C) -> V = proplists:get_value(C,Currencies),
{change,Date,Time,Base,C,V}
end.
and somewhere in your code:
GC = get_currencies(), %% you can store GC in an ets, a server state...
%% but don't forget to refresh it :o)
and use it later
{change,D,T,B,C,V} = GC(<<"ZWL">>),
%% should return {change,{2014,8,15},{2,0,12},<<"USD">>,<<"ZWL">>,322.355006}
[edit]
When I use an external application such as jsx (using rebar itself), I use also rebar and its dependency mechanism to create my own application, in my opinion it is the most convenient way. (In other cases, I use also rebar :o)
Then I build my application using the OTP behaviors (application, supervisor, gen_server...). It is a lot of modules to write, but some of them are very very short (application and supervisors) and they facilitate the application structure (see What is OTP if you are not familiar with this).
In your case, my first idea is to have a gen server that build and store the GC anonymous function in its state, each time it get a cast message such as update_currencies, and provide the answer each time it get a call message such as {get_change,Cur} (and maybe refresh GC if it is undefined or out dated).
You will also have to decide where the errors will be managed - it may be nowhere: if the gen_server does nothing else but answer to this currency query: if something wrong appears it will crash and be restarted by its supervisor - because this code has many interfaces with the out world and so subject to numerous failures (no Internet access, structure of answer change from site, bad currency request from user...)
I figured out my problem.
So first of all, I wasn't thinking of how simple it is to simply count how many elements there are in the tuple. That being said, I realized there were only three.
So the line I needed was
{A,B,C} = Req.
After that, I only wanted to look at the last one (C, the JSON payload), which was a string.
I found out through another source (not to disregard what you told me, Kay!) that you need to use the list functions, since strings and just lists of integers within an ASCII range (I think), in this case list_to_binary.
Once I used this line:
D = list_to_binary(C), and subsequently
E = jsx:decode(D), I got this output:
[{<<"disclaimer">>,
<<"Exchange rates are provided for infor
attempt is made to ensure quality, NO gua
se - please use at your own risk. All usag
s://openexchangerates.org/terms/">>},
{<<"license">>,
<<"Data sourced from various providers w
any kind. Bitcoin data provided by http://
t: https://openexchangerates.org/license/"
{<<"timestamp">>,1408068012},
{<<"base">>,<<"USD">>},
{<<"rates">>,
[{<<"AED">>,3.673128},
{<<"AFN">>,56.479925},
{<<"ALL">>,104.1526},
{<<"AMD">>,413.859001},
{<<"ANG">>,1.789},
{<<"AOA">>,97.913949},
{<<"ARS">>,8.274608},
{<<"AUD">>,1.073236},
{<<"AWG">>,1.79005},
{<<"AZN">>,0.783933},
{<<"BAM">>,1.46437},
{<<"BBD">>,2},
{<<"BDT">>,77.478631},
{<<"BGN">>,1.464358},
{<<"BHD">>,0.377041},
{<<"BIF">>,1546.956667},
{<<"BMD">>,1},
{<<"BND">>,1.246774},
{<<"BOB">>,6.91391},
{<<"BRL">>,2.269462},
{<<"BSD">>,1},
{<<"BTC">>,0.0019393375},
{<<"BTN">>,60.843812},
{<<"BWP">>,8.833083},
{<<"BYR">>,10385.016667},
{<<"BZD">>,1.99597},
{<<"CAD">>,1.090486},
{<<"CDF">>,924.311667},
{<<"CHF">>,0.906833},
{<<"CLF">>,0.02399},
{<<"CLP">>,577.521099},
{<<"CNY">>,6.151637},
{<<"COP">>,1880.690016},
{<<"CRC">>,540.082202},
{<<"CUP">>,1.000688},
{<<"CVE">>,82.049699},
{<<"CZK">>,20.818},
{<<"DJF">>,179.084119},
{<<"DKK">>,5.579049},
{<<"DOP">>,43.43789},
{<<"DZD">>,79.8641},
{<<"EEK">>,11.7064},
{<<"EGP">>,7.150475},
{<<"ERN">>,15.062575},
{<<"ETB">>,19.83205},
{<<"EUR">>,0.748419},
{<<"FJD">>,1.850441},
{<<"FKP">>,0.599402},
{<<"GBP">>,0.599402},
{<<"GEL">>,1.74167},
{<<"GGP">>,0.599402},
{<<"GHS">>,3.735499},
{<<"GIP">>,0.599402},
{<<"GMD">>,39.73668},
{<<"GNF">>,6995.309935},
{<<"GTQ">>,7.839405},
{<<"GYD">>,205.351249},
{<<"HKD">>,7.750754},
{<<"HNL">>,21.04854},
{<<"HRK">>,5.708511},
{<<"HTG">>,44.66625},
{<<"HUF">>,233.8448},
{<<"IDR">>,11685.75},
{<<"ILS">>,3.471469},
{<<"IMP">>,0.599402},
{<<"INR">>,60.82523},
{<<"IQD">>,1178.211753},
{<<"IRR">>,26355.666667},
{<<"ISK">>,115.96},
{<<"JEP">>,0.599402},
{<<"JMD">>,112.604801},
{<<"JOD">>,0.707778},
{<<"JPY">>,102.495401},
{<<"KES">>,88.107639},
{<<"KGS">>,51.991},
{<<"KHR">>,4056.578416},
{<<"KMF">>,368.142141},
{<<"KPW">>,900},
{<<"KRW">>,1021.353328},
{<<"KWD">>,0.283537},
{<<"KYD">>,0.826373},
{<<"KZT">>,182.076001},
{<<"LAK">>,8049.834935},
{<<"LBP">>,1509.068333},
{<<"LKR">>,130.184301},
{<<"LRD">>,91.49085},
{<<"LSL">>,10.56165},
{<<"LTL">>,2.583364},
{<<"LVL">>,0.521328},
{<<"LYD">>,1.244147},
{<<"MAD">>,8.372619},
{<<"MDL">>,13.7178},
{<<"MGA">>,2495.605},
{<<"MKD">>,46.00037},
{<<"MMK">>,972.1784},
{<<"MNT">>,1885},
{<<"MOP">>,7.986291},
{<<"MRO">>,292.0081},
{<<"MTL">>,0.683738},
{<<"MUR">>,30.61748},
{<<"MVR">>,15.37833},
{<<"MWK">>,392.9201},
{<<"MXN">>,13.07883},
{<<"MYR">>,3.175406},
{<<"MZN">>,30.3272},
{<<"NAD">>,10.56145},
{<<"NGN">>,162.303701},
{<<"NIO">>,26.07651},
{<<"NOK">>,6.156902},
{<<"NPR">>,97.66846},
{<<"NZD">>,1.179692},
{<<"OMR">>,0.38501},
{<<"PAB">>,1},
{<<"PEN">>,2.795018},
{<<"PGK">>,2.464545},
{<<"PHP">>,43.68439},
{<<"PKR">>,99.5642},
{<<"PLN">>,3.126203},
{<<"PYG">>,4272.421673},
{<<"QAR">>,3.641297},
{<<"RON">>,3.319212},
{<<"RSD">>,87.8205},
{<<"RUB">>,36.00206},
{<<"RWF">>,690.088},
{<<"SAR">>,3.750583},
{<<"SBD">>,7.258136},
{<<"SCR">>,12.40829},
{<<"SDG">>,5.697837},
{<<"SEK">>,6.857347},
{<<"SGD">>,1.246447},
{<<"SHP">>,0.599402},
{<<"SLL">>,4360},
{<<"SOS">>,841.5678},
{<<"SRD">>,3.275},
{<<"STD">>,18322.733333},
{<<"SVC">>,8.745567},
{<<"SYP">>,150.793749},
{<<"SZL">>,10.56279},
{<<"THB">>,31.87122},
{<<"TJS">>,4.985575},
{<<"TMT">>,2.8501},
{<<"TND">>,1.719698},
{<<"TOP">>,1.889033},
{<<"TRY">>,2.15342},
{<<"TTD">>,6.343484},
{<<"TWD">>,29.99281},
{<<"TZS">>,1661.865},
{<<"UAH">>,13.02466},
{<<"UGX">>,2614.28},
{<<"USD">>,1},
{<<"UYU">>,23.70693},
{<<"UZS">>,2337.773304},
{<<"VEF">>,6.295009},
{<<"VND">>,21191.15},
{<<"VUV">>,94.4875},
{<<"WST">>,2.301222},
{<<"XAF">>,491.283058},
{<<"XAG">>,0.05031404},
{<<"XAU">>,7.6211e-4},
{<<"XCD">>,2.70154},
{<<"XDR">>,0.654135},
{<<"XOF">>,491.394602},
{<<"XPF">>,89.416091},
{<<"YER">>,214.985901},
{<<"ZAR">>,10.55649},
{<<"ZMK">>,5252.024745},
{<<"ZMW">>,6.169833},
{<<"ZWL">>,322.355006}]}]
ok
So this is closer to what I want, but how do I extract a specific currency easily? Like ZWL, for example.