Convert HTML to PDF in Power Automate - html

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

Related

Json Value access in Jquery

I am getting Json Response from ajax page like this
[{"City":"","Email":["khyatiramaswamy9#gmail.com"],"Father\u2019s Name":"Khyati Ramaswamy","Job_Title":[],"Name":"Khyati Ramaswamy","PERSONAL DETAILS":"Khyati Ramaswamy \n\nSobha Hillview \n\nKanakpura road\n\nBangalore - 560052\n\n+91-9920374975 (M)\n\n\n\n\n\n\n\n\n\n\tOBJECTIVE \t\n\n \n\nI seek to give my best on the work front to grow and explore my skills to contribute to the organization that offers professional growth.\n\n\n\n\tWORK EXPERIENCE\t\n\n\n\nDubai4u Investments 2019\n\n\n\nSales and Operations Manager\n\n\n\nResponsibilities \n\n\u2022 Responsible for overall operations of the company\n\n\u2022 Managing Sales Team \n\n\u2022 Managing overall coordination with Clients\n\n.\n\nHop \u2013 Jump \t\t\t\t\t\t\t\t\t\t2004 - 2006\n\n\n\nI started my own business \u2018Hop \u2013 Jump\u2019 a specialist at event planning and organizing\n\n\n\nResponsibilities\n\n\n\nI was the founder of the Company that specialized in customizing parties and events for Clients \n\nI established a strong network with caterers, decorators, anchors, performing artists, party suppliers that could help set up the event as per the specifications and budgets of the client.\n\nWe generated business through word of mouth, partnering with caterers & decorators to generate leads\n\n\n\n\n\nHathway\t\t\t\t\t\t\t\t\t\t2003 - 2004\n\n\n\nWorked a Public Relations Officer \n\n\n\nResponsibilities\n\n\n\nUndertook collections and follow up \n\n\n\n\n\nNisus Integrated Marketing Solutions Pvt Ltd. Media\t\t\t\t2000 - 2002\n\n\n\nWorked a Business Development Manager \n\n\n\nResponsibilities\n\n\n\nGrow the market for Nisus by working out solutions that establish it as a one destination marketing solutions provider.\n\nDrive not just regular but also new business for Nisus\n\nMarket research to recognize changing requirements and trends to offer better solutions to clients\n\nProactively understanding client requirements and offering integrated marketing solutions \n\nLooking at non convention business opportunities and tapping its potential\n\nEstablish relations with vendors who are more competitive and upbeat\n\n\n\n\n\nNisus Integrated Marketing Solutions Pvt Ltd. Media\t\t\t\t1197 - 1998\n\n\n\nWorked a Sales and development Executive \n\n\n\nResponsibilities\n\n\n\nLead Generation and follow up with potential customers to maximize business opportunities\n\nBuild and manage database to pool in more business \n\nTele marketing to establish and sell Nisus\u2019 marketing solutions across media.\n\n\n\n\n\n\tEDUCATION\t\n\n\n\nQualification: \tPostgraduate Diploma in Advertising and Marketing \n\nFrom: \t\tBharti Vidya Bhavan\u2019s Rajendra Prasad Institute of Communication and Management \t\n\nYear: \t\t2000-2001\n\n\n\nQualification: \tB. Com \n\nFrom: \t\tNagpur University\t\n\nYear: \t\t1999-2000\n\n \n\n\tINTERESTS \t\n\n\n\nReading \n\nEvents Planning and Organizing\n\nTravelling & backpacking\n\nCooking and Nutrition Planning\n\n\n\n\tPERSONAL DETAILS\t\n\n\n\nDate of Birth: 9th November 1979\n\nGender: Female\n\nMarital Status: Married\n\nLanguages Know: English, Guajarati, Hindi\n\nBasic Skills: Word, Power Point\n\nEmail Address- khyatiramaswamy9#gmail.com","Phone":["+91-9920374975"],"Skill":[],"State":"","colleges":[],"pin_code":"560052","spoken_languages":["English","Hindi"],"universities":[]}]
when i can the city value like this -> alert(data.city) it coming like undefined.
Ajax code :
<div class="col-lg-6">
<span class="pf-title">Resume</span>
<div class="pf-field">
<input type="file" name="resume" id="resume" accept=".doc,.docx,.pdf" value="" class="resume"/> <?php if($row['Upload_Resume'] == "" || $row['Upload_Resume'] == "NULL") { ?> Update Resume <?php } else{ ?> <a href="All-resumes/<?php echo $row['Upload_Resume']; ?>" target="blank" class="btn btn-danger" style="font-size: 10px;" >View Or Download Resume</a><?php } ?>
<i class="fa fa-upload"></i>
</div>
</div>
$(document).ready(function(){
$(".resume").on('change', function(){
var name = $("#resume").val();
var fd = new FormData();
var files = $('#resume')[0].files;
if(files.length > 0 ){
fd.append('file',files[0]);
$.ajax({
url: 'get_resume_data.php',
type: 'post',
data: fd,
contentType: false,
processData: false,
success: function(dataa){
var dataVal = JSON.parse( dataa );
alert(dataVal);
alert(dataVal[0].City);
},
});
}else{
alert("Please select a file.");
}
});
});
Ajax Page code:
$filename = $_FILES['file']['name'];
$files =$filename;
$postData = curl_file_create(realpath($files),mime_content_type($files),basename($files));
$data = array('file' => $postData);
$request = curl_init('');
curl_setopt_array($request, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $data,
));
$result = curl_exec($request);
curl_close($request);
echo $result;
This is what i have trying to do,Thanks in Advance
In comments you mention
its only alert [object][object] when alert(data),alert(data[0]),but alert(data[0].City) return null value
This is only possible if the sample data you provided in your question is not actually the case (in all scenarios).
However if we go by your sample ajax response, we can test it for valid json by directly assigning it to a variable. Note that in your actual code you wouldn't do this, so this ANSWER is to only illustrate that the json in your sample is valid.
let data = [{"City":"Hello","Email":["khyatiramaswamy9#gmail.com"],"Father\u2019s Name":"Khyati Ramaswamy","Job_Title":[],"Name":"Khyati Ramaswamy","PERSONAL DETAILS":"Khyati Ramaswamy \n\nSobha Hillview \n\nKanakpura road\n\nBangalore - 560052\n\n+91-9920374975 (M)\n\n\n\n\n\n\n\n\n\n\tOBJECTIVE \t\n\n \n\nI seek to give my best on the work front to grow and explore my skills to contribute to the organization that offers professional growth.\n\n\n\n\tWORK EXPERIENCE\t\n\n\n\nDubai4u Investments 2019\n\n\n\nSales and Operations Manager\n\n\n\nResponsibilities \n\n\u2022 Responsible for overall operations of the company\n\n\u2022 Managing Sales Team \n\n\u2022 Managing overall coordination with Clients\n\n.\n\nHop \u2013 Jump \t\t\t\t\t\t\t\t\t\t2004 - 2006\n\n\n\nI started my own business \u2018Hop \u2013 Jump\u2019 a specialist at event planning and organizing\n\n\n\nResponsibilities\n\n\n\nI was the founder of the Company that specialized in customizing parties and events for Clients \n\nI established a strong network with caterers, decorators, anchors, performing artists, party suppliers that could help set up the event as per the specifications and budgets of the client.\n\nWe generated business through word of mouth, partnering with caterers & decorators to generate leads\n\n\n\n\n\nHathway\t\t\t\t\t\t\t\t\t\t2003 - 2004\n\n\n\nWorked a Public Relations Officer \n\n\n\nResponsibilities\n\n\n\nUndertook collections and follow up \n\n\n\n\n\nNisus Integrated Marketing Solutions Pvt Ltd. Media\t\t\t\t2000 - 2002\n\n\n\nWorked a Business Development Manager \n\n\n\nResponsibilities\n\n\n\nGrow the market for Nisus by working out solutions that establish it as a one destination marketing solutions provider.\n\nDrive not just regular but also new business for Nisus\n\nMarket research to recognize changing requirements and trends to offer better solutions to clients\n\nProactively understanding client requirements and offering integrated marketing solutions \n\nLooking at non convention business opportunities and tapping its potential\n\nEstablish relations with vendors who are more competitive and upbeat\n\n\n\n\n\nNisus Integrated Marketing Solutions Pvt Ltd. Media\t\t\t\t1197 - 1998\n\n\n\nWorked a Sales and development Executive \n\n\n\nResponsibilities\n\n\n\nLead Generation and follow up with potential customers to maximize business opportunities\n\nBuild and manage database to pool in more business \n\nTele marketing to establish and sell Nisus\u2019 marketing solutions across media.\n\n\n\n\n\n\tEDUCATION\t\n\n\n\nQualification: \tPostgraduate Diploma in Advertising and Marketing \n\nFrom: \t\tBharti Vidya Bhavan\u2019s Rajendra Prasad Institute of Communication and Management \t\n\nYear: \t\t2000-2001\n\n\n\nQualification: \tB. Com \n\nFrom: \t\tNagpur University\t\n\nYear: \t\t1999-2000\n\n \n\n\tINTERESTS \t\n\n\n\nReading \n\nEvents Planning and Organizing\n\nTravelling & backpacking\n\nCooking and Nutrition Planning\n\n\n\n\tPERSONAL DETAILS\t\n\n\n\nDate of Birth: 9th November 1979\n\nGender: Female\n\nMarital Status: Married\n\nLanguages Know: English, Guajarati, Hindi\n\nBasic Skills: Word, Power Point\n\nEmail Address- khyatiramaswamy9#gmail.com","Phone":["+91-9920374975"],"Skill":[],"State":"","colleges":[],"pin_code":"560052","spoken_languages":["English","Hindi"],"universities":[]}]
alert( data[0].City ); // alerts Hello, not null
I only changed the City property value of [0] to "Hello" as opposed to an empty string. However, even an empty string will not return null.
I didn't want to keep extending comments and provided this answer only to illustrate that something else must be wrong with your code that you don't show.

Extract academic publication information from IDEAS

I want to extract the list of publications from a specific IDEAS's page. I want to retrieve information about name of the paper, authors, and year. However, I am bit stuck in doing so. By inspecting the page, all information is inside the div class="tab-pane fade show active" [...], then with h3 we do have the year of publication while inside each li class="list-group-item downfree" [...] we can find each paper with relative author (as showed in this image). At the end, what I willing to obtain is a dataframe containing three columns: title, author, and year.
Nonetheless, while I am able to retrieve each paper's name, when I want to add also year and author(s) I get confused. What I wrote so far is the following short code:
from requests import get
url = 'https://ideas.repec.org/s/rtr/wpaper.html'
response = get(url)
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
containers = soup.findAll("div", {'class': 'tab-pane fade show active'})
title_list = []
year_list = []
for container in containers:
year = container.findAll('h3')
year_list.append(int(year[0].text))
title_containers = container.findAll("li", {'class': 'list-group-item downfree'})
title = title_containers[0].a.text
title_list.append(title)
What I get are two list of only one element each. This because the initial containers has the size of 1. Regarding instead how to retrieve author(s) name I have no idea, I tried in several ways without success. I think I have to stripe the titles using 'by' as separator.
I hope someone could help me or re-direct to some other discussion which face a similar situation. Thank you in advance. Apologize for my (probably) silly question, I am still a beginner in web scraping with BeautifulSoup.
You can get the desired information like this:
from requests import get
import pprint
from bs4 import BeautifulSoup
url = 'https://ideas.repec.org/s/rtr/wpaper.html'
response = get(url)
soup = BeautifulSoup(response.text, 'html.parser')
container = soup.select_one("#content")
title_list = []
author_list = []
year_list = [int(h.text) for h in container.find_all('h3')]
for panel in container.select("div.panel-body"):
title_list.append([x.text for x in panel.find_all('a')])
author_list.append([x.next_sibling.strip() for x in panel.find_all('i')])
result = list(zip(year_list, title_list, author_list))
pp = pprint.PrettyPrinter(indent=4, width=250)
pp.pprint(result)
outputs:
[ ( 2020,
['The Role Of Public Procurement As Innovation Lever: Evidence From Italian Manufacturing Firms', 'A voyage in the role of territory: are territories capable of instilling their peculiarities in local production systems'],
['Francesco Crespi & Serenella Caravella', 'Cristina Vaquero-Piñeiro']),
( 2019,
[ 'Probability Forecasts and Prediction Markets',
'R&D Financing And Growth',
'Mission-Oriented Innovation Policies: A Theoretical And Empirical Assessment For The Us Economy',
'Public Investment Fiscal Multipliers: An Empirical Assessment For European Countries',
'Consumption Smoothing Channels Within And Between Households',
'A critical analysis of the secular stagnation theory',
'Further evidence of the relationship between social transfers and income inequality in OECD countries',
'Capital accumulation and corporate portfolio choice between liquidity holdings and financialisation'],
[ 'Julia Mortera & A. Philip Dawid',
'Luca Spinesi & Mario Tirelli',
'Matteo Deleidi & Mariana Mazzucato',
'Enrico Sergio Levrero & Matteo Deleidi & Francesca Iafrate',
'Simone Tedeschi & Luigi Ventura & Pierfederico Asdrubal',
'Stefano Di Bucchianico',
"Giorgio D'Agostino & Luca Pieroni & Margherita Scarlato",
'Giovanni Scarano']),
( 2018, ...
I got the years using a list comprehension. I got the titles and authors by appending a list to the title_list and title_list for the required elements in each div element with the class panel-body again using a list comprehension and using next.sibling for the i element to get the authors. Then I zipped the three lists and cast the result to a list. Finally I pretty printed the result.

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 :)

How could *data inter-dependent* <select> dropdowns in rails be populated quickly?

Users need to select a car.
We have several dropdowns when picking a car in order to pick the year, make, model and submodel.
Initially we don't know what to use for the select options for make/model/submodel as they are interdependent.
Once we pick year we use ajax to make requests which query ActiveRecord to populate the make dropdown.
Then when we pick make we use ajax to query and populate the model dropdown.
Then when we pick model we ajax to query and populate the submodel dropdown.
The problem is that this is a lot of separate network requests and in real-world conditions of low bandwidth, network issues, etc. quite often there are pauses severely impacting the user experience and occasionally leading to failures.
What approaches could help avoid all these network requests. In there an approach would could store all of the several thousand makes-model combinations on the client browser?
Currently the data is stored in a sql database accessed via ActiveRecord in the Rails framework. Each dropdown selection results in another query because yuou can't show populate and show make until you know year and you can't populate and show model until you know make. Same for submodel (though I've omitted submodel from the rest of this post for simplicity!).
Would session (http://simonsmith.io/speeding-things-up-with-sessionstorage/) storage of the JSON data for 10,000 combinations be possible? I see that sessionStorage can generally be relied on to have at least 5MB(5,200,000 bytes) so that gives me 5200000/10000= 520 bytes per record. Probably enough? If this persists for the session and across pages then in many cases we could actually kick this off on the previous page and if that had time to finish we wouldn't need the external call at all on the relevant (next) page.
We would need to refresh that data either occasionally or on demand as new year-make-models are added periodically (several times a year).
Ultimately I think the solution here could be very useful to a large number of applications and companies. The example here of picking a vehicle itself it used by dozens of major car insurance websites (who all do the multiple calls right now). The general appraoch of storing client side data for relatioship dependent sdropdown could also mapply in many other situations such as online shopping for make-brand-year-model. The backend framework to populate sessionStorage could also be done via different backend frameworks.
Another options might be to try google's Lovefield - https://github.com/google/lovefield More at https://www.youtube.com/watch?v=S1AUIq8GA1k
It's open source and works in ff, chrome, IE, Safari, etc.
Seems like sessionStorage might be better for our (considerable) business than basing it on a google 100 day dev thing - though it is open source.
Hello you can create the JSON object
for all the detail and based on the Value selected you can loop the array and populate the value. Let me
var cardetail = [{
"name": "MARUTI",
"model": [{
"name": "SWIFT",
"year": ["2005", "2006", "2008"]
}, {
"name": "ALTO",
"year": ["2009", "2010", "2011"]
}]
}, {
"name": "Hundai",
"model": [{
"name": "I20",
"year": ["2011", "2012", "2013"]
}, {
"name": "I20",
"year": ["2013", "2014", "2015"]
}]
}];
var currentCumpany = null;
var currentModel = null;
$(document).ready(function() {
$("#company").append("<option value=''>Select Company</option>");
for (i = 0; i < cardetail.length; i++) {
$("#company").append("<option value='" + cardetail[i].name + "'>" + cardetail[i].name + "</option>");
};
$("#company").change(function() {
for (i = 0; i < cardetail.length; i++) {
if (cardetail[i].name == $("#company").val()) {
currentCumpany = cardetail[i];
}
};
$("#model").html("");
for (i = 0; i < currentCumpany.model.length; i++) {
$("#model").append("<option value='" + currentCumpany.model[i].name + "'>" + currentCumpany.model[i].name + "</option>");
};
});
$("#company").change(function() {
for (i = 0; i < cardetail.length; i++) {
if (cardetail[i].name == $("#company").val()) {
currentCumpany = cardetail[i];
}
};
$("#model").html("");
for (i = 0; i < currentCumpany.model.length; i++) {
$("#model").append("<option value='" + currentCumpany.model[i].name + "'>" + currentCumpany.model[i].name + "</option>");
};
});
$("#model").change(function() {
for (i = 0; i < currentCumpany.model.length; i++) {
if (currentCumpany.model[i].name == $("#model").val()) {
currentModel = currentCumpany.model[i];
}
};
$("#year").html("");
for (i = 0; i < currentModel.year.length; i++) {
$("#year").append("<option value='" + currentModel.year[i] + "'>" + currentModel.year[i] + "</option>");
};
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="company"></select>
<select id="model"></select>
<select id="year"></select>
First, unless the requisite bandwidth is too expensive you could conceivably check the cache and then start making requests for popular makes/models/submodels as soon as (or even before) the user picks a year and cache it. There's even a full RDBMS for the browser now (full disclosure: its new and I haven't played with it much) which sits atop indexDB.
In terms of picking which ones to preload, you could do it based on units produced, units sold, car and driver magazine rankings, data-mining your actual users' requests, whatever.
I'm of the opinion that from a UX perspective you should at least be caching the requests the user actually makes and offering an option on load to jump right back to the last year/make/model they searched for rather than having them enter it all fresh each visit. Having popular vehicles preloaded only makes things easier. How much you want to push the envelope with predictive analysis of what a given user is likely to search for is up to your team skills/budget/time constraints.
I realize that this isn't a full answer per se, I'm not sure as stated the question has one (e.g. 'use this strategy/framework/library and all your problems will magically disappear! it even makes julienned fries!'). But if faced with this kind of problem my first thought is how to get more (hopefully relevant) data to the client sooner, which hopefully translates to faster (in the UX sense of fast).
I would also recommend that you have that popular data in json files to request rather than have to hit Rails/ActiveRecord/Database server each time. That alone would shave valuable milliseconds off your response times (not to mention usage load on those machines).
Its not like that data really changes, a 2009 Toyota Rav 4 has the same specs it did in...2009.

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.