Using openexchangerates API for currency conversion using JS/JQuery - javascript

I have managed to place JSON data into a form-control using JS which is this:
$("#getRates").ready(function () {
$.getJSON("http://openexchangerates.org/api/currencies.json?app_id="APP_ID", function (data) {
console.log(data);
for (var value in data) {
if (data.hasOwnProperty(value)) {
var text = document.createTextNode(value);
var select = document.getElementsByClassName('form-control')[1];
select.appendChild(document.createElement('option')).appendChild(text);
}
}
The current JSON file only contains the countries names but I wish to use the a different JSON file which is called Latest.JSON and contains the most recent rates, but it has these fields:
"license":
"timestamp": 1417258840,
"base": "USD",
"rates": {
"AED": 3.672743,
"AFN": 57.800375,
How can I just use the append the "rates" to the form-function and use the rates for the conversion?
As I have previously tried I just console.log and receive "License" "timestamp" "base" but no rates?
Not after specific answer maybe just some direction towards where to look?

$.getJSON("http://openexchangerates.org/api/latest.json?app_id=b65b6f0a06204a6087bab9a63a5845b7", function (data) {
console.log(data.rates);
for (var key in data.rates) {
if (data.rates.hasOwnProperty(key)) {
var text = document.createTextNode(key);
var select = document.getElementsByClassName('form-control')[1];
console.log(select);
select.appendChild(document.createElement('option')).appendChild(text);
}
}
for (var value in data.rates) {
if (data.rates.hasOwnProperty(value)) {
var text = document.createTextNode(value);
var select = document.getElementsByClassName('form-control')[2];
console.log(select);
select.appendChild(document.createElement('option')).appendChild(text);
}
}
});
});
I changed the var key to data.rates and this seems to of solved it.
This now populates both of my form-cotrols with the data.rates values from latest.json ..
The console.log() is just for my own usage..

Related

How to merge array into JSON array

I have a JSON file that I need to add Comments into and then update the file.
I've created an array for the new comments
//ADDING NEW COMMENTS
//add new comment within project
$scope.updatecomments = [];
$scope.addnewcomment = function() {
$scope.updatecomments.push({
"Author": "test",
"Text": $scope.NewComment
})
}
I can post the new comments into the JSON file but it overrides the past comments.
I have tried to merge the older comments with the new comments with the following
$scope.updatecomments = [];
$scope.addnewcomment = function() {
$scope.updatecomments.push({"Author": "test" ,"Text": $scope.NewComment}).concat($scope.Comments, $scope.updatecomments);
}
$scope.updatecomments = [].concat($scope.updatecomments,
$scope.projectDetails.Comments);
$scope.addnewcomment = function() {
$scope.updatecomments.push({
"Author": "test",
"Text": $scope.NewComment
});
}
I also tried making a new function that when called combines the two and then post the combined array
$scope.combine = [];
$scope.combineComments = function (){
var jsonStr = $scope.projectDetails.Comments;
var obj = JSON.parse(jsonStr);
obj['Comments'].push({"Author":"Test","Text":$scope.NewComment});
jsonStr = JSON.stringify(obj);
}
}
I have been going over this for the past few days now and can't seem to get it. Any help would be greatly appreciated!
EDIT
Sample Data of already existing data in JSON file
{
"Comments":[{
"Author": "John Doe",
"Text": "Work completed"
}]
}
Want to add to this (is from html input text tag) stored as NewComment
{
"Comments":[{
"Author": "Test",
"Text": "Project flagged"
}]
}
Edit 2
This is how I'm getting my projects data
/FIND PROJECTS - ADD TO LIST
$scope.projectList = [];
for (var id = 0; id < 30; id++) {
var targetURL = 'https://happybuildings.sim.vuw.ac.nz/api/sooleandr/project.'+id+'.json';
$http.get(targetURL).then(
function successCall(response){
$scope.projectList.push(response.data);
}
);
}
I then use this to access the selected information
//script
$scope.showData = function(x){
$scope.projectDetails = x;
};
//html
<ul class = 'pList'>
<li ng-repeat = 'x in projectList' class = 'pbList'>
<button class = 'pbutton' ng-click = 'showData(x)'>
<label ng-model ='pID'>Project ID: </label>{{x.ProjectID}} <br>
<label id ='pName'>Project Name: </label> {{x.Name}} <br>
<label id ='bID'>Building ID: </label>{{x.BuildingID}}<br>
<label id ='sDate'>Start Date: </label>{{x.StartDate}}
</button>
</li>
</ul>
Then I have the following variables to post
$scope.updateProject = function (projectDetails){
var updateproject = {
"ProjectID":$scope.projectDetails.ProjectID,
"Name":$scope.projectDetails.Name,
"BuildingID":$scope.projectDetails.BuildingID,
"StartDate":$scope.projectDetails.StartDate,
"EndDate":$scope.projectDetails.EndDate,
"Status":$scope.projectDetails.Status,
"ContactPerson":$scope.projectDetails.ContactPerson,
"Contractor":$scope.projectDetails.Contractor,
"ProjectManager":$scope.projectDetails.ProjectManager,
"Works": $scope.projectDetails.works,
"Comments":$scope.updatecomments,
};
$http.post("https://happybuildings.sim.vuw.ac.nz/api/sooleandr/update.project.json", updateproject).then(
function success(){
alert("Project Successfully Posted");
},
function error(){
alert("Error: Couldn't post to server");
}
)
};
It posts perfectly fine but it currently overrides the comments. I want to be able to add a new comment and still keep all the past comments. So I want to be able to push/add the comments into the full POST.JSON array.
Hope this makes a bit more sense
OK, updating answer after looking at provided code.
It appears you may be under the impression that $scope.projectDetails.Comments is a JSON string, when, in fact.. it's the actual Comments array.
I would try this for the addnewcomment function:
//ADDING NEW COMMENTS
//add new comment within project
$scope.updatecomments = undefined;
$scope.addnewcomment = function() {
$scope.updatecomments = $scope.updatecomments || $scope.projectDetails.Comments;
$scope.updatecomments.push({
"Author": "test",
"Text": $scope.NewComment
})
}
IF it just so happens to be a JSON string (highly unlikely), then I would update the combine function to this:
$scope.combineComments = function (){
var jsonStr = $scope.projectDetails.Comments;
var obj = JSON.parse(jsonStr);
obj.push({"Author":"Test","Text":$scope.NewComment});
jsonStr = JSON.stringify(obj);
}
}
EDIT
I'm adding another answer from my original because of the possibility things will break when there are no updated comments
//ADDING NEW COMMENTS
//add new comment within project
$scope.addnewcomment = function() {
$scope.projectDetails.Comments.push({
"Author": "test",
"Text": $scope.NewComment
})
}
Then in the POST, change to:
"Comments":$scope.projectDetails.Comments
I have figured out how to combine the two with
$scope.combinecomments = [];
$scope.combine = function (){
$scope.combinecomments.push($scope.projectDetails.Comments);
$scope.combinecomments.push($scope.updatecomments);
}
Except now it doesn't post the combined comments
$scope.ProjectID='$scope.ProjectID';
$scope.Name = '$scope.Name';
$scope.BuildingID = '$scope.BuildingID';
$scope.StartDate = '$scope.StartDate';
$scope.EndDate = '$scope.EndDate';
$scope.Status = '$scope.Status';
$scope.ContactPerson = '$scope.ContactPerson';
$scope.Contractor ='$scope.Contractor';
$scope.ProjectManager = '$scope.ProjectManager';
$scope.Works = '$scope.works';
$scope.Comments ='$scope.comments';
$scope.updateProject = function (projectDetails){
var updateproject = {
"ProjectID":$scope.projectDetails.ProjectID,
"Name":$scope.projectDetails.Name,
"BuildingID":$scope.projectDetails.BuildingID,
"StartDate":$scope.projectDetails.StartDate,
"EndDate":$scope.projectDetails.EndDate,
"Status":$scope.projectDetails.Status,
"ContactPerson":$scope.projectDetails.ContactPerson,
"Contractor":$scope.projectDetails.Contractor,
"ProjectManager":$scope.projectDetails.ProjectManager,
"Works": $scope.projectDetails.works,
"Comments":$scope.combinecomments,
};
$http.post("https://happybuildings.sim.vuw.ac.nz/api/sooleandr/update.project.json", updateproject).then(
function success(){
alert("Project Successfully Posted");
},
function error(){
alert("Error: Couldn't post to server");
}
)
};
It successfully posts the project except for the comments. It doesn't seem to like my combined array. When I post $scope.updatecomments it will post that but not the $scope.combinecomments.
I'll make a new question for this.

Razor - Converting Json result from controller to a complex object

i have a partial view "_SearchPanel" that has year list dropdown, a classes multiselect control, (some other drop downs - ommitted) and a search button.
I want that when i change selection in year list drop down, only my classes list is refreshed/updated, and not the whole partial view on page.
So i use a JsonResult action in my controller (as opposed to the first time load)
public JsonResult BindClasses(int yearId)
{
ClassRepository repClass = new ClassRepository("name=ge");
YearRepository repYear = new YearRepository("name=ge");
var dataClass = repClass.GetClassesByYear(yearId);
var groupedClassOptions = dataClass.GroupBy(x => x.grade).Select(x => new OptionGroupVM()
{
GroupName = "Grade " + x.Key.ToString(),
Options = x.Select(y => new OptionVM()
{
Value = y.classID.ToString(),
Text = y.classname
})
});
return Json(groupedClassOptions);
}
My javascript
var dropDownYear = $('#ddlYear');
dropDownYear.change(function(){
$("#classList").load(url, {yearId: $(this).val()}, function(result){
setOptions($('#classList'), #Html.Raw(Json.Encode(new List<int>(){})), result);
});
});
now the problem is this result is not considered as an object as was the first time (onpageload) here:
jQuery(function ($) {
setOptions($('#classList'), #Html.Raw(Json.Encode(Model.SelectedClasses)), #Html.Raw(Json.Encode(Model.ClassOptions)));
}
How do i correct/cast it to be considered as Model.ClassOptions(type: GroupOptionsVM List) object instead of a Json
What I have tried
var url = '#Url.Action("BindClasses", "Maps")';
var dropDownYear = $('#ddlYear');
dropDownYear.change(function(){
$("#classList").load(url, {yearId: $(this).val()}, function(result){
#{var x = new List<OptionGroupVM>();}
x = result;
setOptions($('#classList'), #Html.Raw(Json.Encode(new List<int>(){})), x);
});
});
this gives me some syntax errors!!
UPDATE
[Referring to the previous question Stephen linked in comments]
Since i had to do it for two dropdown lists with slight difference i had created setOptions function in my script
function setOptions(listBox, selected, groups) {
// Generate options
createGroupedOptions(listBox, selected, groups);
// Attach plug-in
listBox.multiselect({ enableClickableOptGroups: true, onChange: function(){
var selectedClassItems = this.$select.val();
} });
}
function createGroupedOptions(element, selected, groups) {
for (var i = 0; i < groups.length; i++) {
var group = groups[i];
var groupElement = $('<optgroup></optgroup>').attr('label', group.GroupName);
for (var j = 0; j < group.Options.length; j++) {
var option = group.Options[j];
var optionElement = $('<option></option>').val(option.Value).text(option.Text);
if (selected) {
if (selected.toString().indexOf(option.Value) >= 0) {
optionElement.attr('selected', 'selected')
}
} else {
if (option.IsSelected) {
optionElement.attr('selected', 'selected')
}
}
$(groupElement).append(optionElement);
}
$(element).append(groupElement);
}
}
CALLING setOptions function
setOptions($('#classList'), #Html.Raw(Json.Encode(Model.SelectedClasses)), #Html.Raw(Json.Encode(Model.ClassOptions)));
setOptions($('#indicatorList'), #Html.Raw(Json.Encode(Model.SelectedIndicators)), #Html.Raw(Json.Encode(Model.IndicatorOptions)));
Your returning json, so using .load() makes no sense (you would typically use that when the method your calling returns a partial view).
Change your script to create the <optgroup> and <option> elements based on your data your method returns
var url = '#Url.Action("BindClasses", "Maps")';
var dropDownYear = $('#ddlYear');
dropDownYear.change(function() {
$.post(url, { yearId: $(this).val() }, function(data) {
$.each(data, function(index, item) {
var group = item.GroupName;
// use the above to build your <optgroup> element
$.each(item.Options, function(index, item) {
var value = item.Value;
var text = item.Text;
// use the above to build your <option> elements and append to the <optgroup> element
});
// append the <optgroup> to the <select id="classList"> element
});
});
});
Note the details of the code for generating the elements are in the answer to your previous question
You are trying to mix client side code (jQuery) with server side code (.NET) and it won't work. #Html.Raw and JsonEncode are server side methods. You can't use them after the page loads.
In essence, you need to either use jQuery for all of your page interaction and manage the state of the page on the client side or use full MVC (postback) and do everything on the server.
There are technically other options but I just wanted to address the fundamental issue with what you have tried so far.

Javascript: SHA512 value convert to JSON object

I already crypt the variable 'getShaValue' to sha512. Then combine it with many variable like 'name','ic' using JSON.stringify. But when I debug my JSON object, the value of SHA512 didn't show the right value. If I only debug the value before convert it into JSON, it show the right value.
Here is my function to crypt the value
self.sha512 = function () {
var value = self.generateSHAvalue();
var getShaValue= CryptoJS.SHA512(value);
return getShaValue;
};
I combine it with many variable
var authToken = SHA.sha512();
var requestData = JSON.stringify({
name: "Test",
authToken: authToken
})
console.log("requestData: " + JSON.stringify(requestData));
The result of the console is
{
"name": "Test",
"authToken": '"$super":{"$super":{}},"words":[1157899753,2720090447,1588426441,2244605341,2288345873,3771352114,2976397435,3171064119,-130018106,2601059156,3822838925,2519334849,1988499628,2785343384,-556559616,-1270654637],"sigBytes":64'
}
But it should be like this:
{
"name": "Test",
"authToken": "21507C7061D3F45058A95751E2FB332DD68F6A2ADC2039DE4341199643E12ADEFB8DF603C3F 34E71FB447F46B82BC5DC7BD2B81B83B389D8950583BEFB424676"
}
Can anyone help me. Thanks.
You included the binary digest in the json. Try converting it to hex first:
self.sha512 = function () {
var value = self.generateSHAvalue();
var shaHex = CryptoJS.SHA512(value).toString(CryptoJS.enc.Hex);
return shaHex ;
};

How to insert data in json after crawling through casperjs?

I wrote code that parsing a lot of words (innerHTML) from some webpages.
and I'd like to insert data to json file directly..
Here is my js code...
var words = [];
var casper = require('casper').create();
function getWords() {
var words = document.querySelectorAll('td.subject a');
return Array.prototype.map.call(words, function(e) {
return e.innerHTML;
});
}
casper.start('http://www.todayhumor.co.kr/board/list.php?table=bestofbest', function() {
words = this.evaluate(getWords);
});
for (var i=2; i <=5; i++) {
casper.thenOpen('http://www.todayhumor.co.kr/board/list.php?table=bestofbest&page='+i, function() {
words = words.concat(this.evaluate(getWords));
});
}
casper.run(function() {
// echo results in some pretty fashion
this.echo(words.length + ' links found:').exit();
this.echo(words.join('\n')).exit();
});
and
I run this code through terminal like this!
username#wow:~/workspace/app/assets/javascripts $ casperjs application.js
and the result is (for example)
150 words found:
apple
banana
melon
kiwi
citrus
watermelon
passionfruit
mango
orange
...
So I want to insert this data in "word" part of my json file (example code of json below)
and make other columns("type": "fruit" and "spell":) automatically added
{ "my_initial_words": [
{
"type": "fruit",
"word": "apple",
"spell": "ap"
},
{
"type": "fruit",
"word": "banana",
"spell": "ba"
},
{
"type": "fruit",
"word": "melon",
"spell": "me"
}
]
}
----------------------------------------------------------------------------
thanks for adding more answer!..
but I couldn't catch where should I put these code
Could you tell me once more that... Which code you gave me executes "Saving the results to JSON file?" because I have to read json file(makeyourap.json) in my seeds.rb file like this
require 'json'
file = File.open(Rails.root.join('db','makeyourap.json'))
contents = file.read
json = ActiveSupport::JSON.decode(contents)["my_initial_words"]
So, something like this?
function makeTypeObject(name, type) {
return {
name: name,
type: type,
spell: name.substr(0,2)
};
}
var wordDesc = words.map(function (word) {
return makeTypeObject(word, "fruit");
});
var finalObject = {
my_initial_words: wordDesc
};
var jsonString = JSON.stringify(finalObject);
// if you want prettyprint, try JSON.stringify(finalObject, null, "\t");
I hope this helps.
Write to file via casper
If you want to have a file from which you read and write, appending content, you can do it like this:
var fs = require('fs');
var FILENAME = 'makeyourap.json';
function add_new_fruits(fruits) {
var data;
if ( fs.isFile(FILENAME) ) {
data = fs.read(FILENAME);
} else {
data = JSON.stringify({'my_initial_words' : [] });
}
var json = JSON.parse(data);
fruits.forEach(function(word) {
json.my_initial_words.push({"type": "fruit",
"name": word,
"spell": word.slice(0,2)});
});
data = JSON.stringify(json, null, '\t');
fs.write(FILENAME, data, "w");
}
Use this instead of the older this.echo. Just call it as
casperjs application.js
This either reads the object from a file, or creates it if it does not exist. Then, it appends each new object from the new fruits (including duplicates), and writes it back to FILENAME.
Previous approach: how to roll your own
create Object
So first, you want to create an object that only has the parameter my_initial_words with values as above.
You can create a function via
function createFinal(wordArray) {
var out = [];
wordArray.forEach(function(word) {
out.push({"type": "fruit", "name": word, "spell": word.slice(0,2)});
});
return out;
}
to create the array. Then, create the object via
var my_object = { "my_initial_words": createFinal(words) };
to JSON
Javascript has a built-in JSON-object. With a javascript-object like
var my_object = { "my_initial_words": ...
as above, use
JSON.stringify(my_object)
to get the JSON representation to write.
Older: write to file via redirection
Before, you had
this.echo(words.join('\n')).exit();
which gave you the basic list. Using this.echo, try replacing this by
var my_object = { "my_initial_words": createFinal(words) };
this.echo(JSON.stringify(my_object)).exit();
This prints to standard output. Just remove the other this.echo line (150 words found) and redirect the output via
casperjs application.js > makeyourap.json
If you want to write to file in casperjs, look at write-results-into-a-file-using-casperjs.

CRM Javascript Automatically Populated a Look-up Value with a specific field

I'm trying to write a javascript on CRM Phone Call page. We have a custom look-up field called new_department, and we want to automatically populate the field with value "IT" (there should be one) when the form is opened.
The thing is we have a separate Dev and Production CRM link therefore I cannot just assign a hard-coded GUID value into this field. So first I wrote a Rest Retrieve Multiple to get the correct department.
Then my problem is I'm not sure about the result returned from this Retrieve Multiple. How do I grab just the GUID from Rest? I'm seeing that this is a type of {Object}. Then lastly how do I go about setting the lookup value after retrieving the {Object}? Any help is greatly appreciated.
Here is my code.
function phonecall() {
var formType = Xrm.Page.ui.getFormType();
if (formType == 1) //create
{
//RetrieveMultiple function
var DepartmentId = getITDepartment();
//set the lookup value
var ID = DepartmentId.id;
var departmentValue = new Array();
departmentValue[0] = new Object();
departmentValue[0].id = DepartmentId;
departmentValue[0].name = 'IT';
userValue[0].entityType = "new_department";
Xrm.Page.getAttribute("new_department").setValue(departmentValue);
}
}
function getITDepartment()
{
XrmServiceToolkit.Rest.RetrieveMultiple("new_departmentSet", "$select=new_departmentId&$filter=new_name eq 'IT'",
function (results) {
if (results.length > 0)
resultList = results;
}, function (error) { alert(error); }, function onComplete() { }, false);
return resultList;
}
Thanks much.
I'm not familiar with XrmServiceToolkit but here how code could look like to work properly - I replaced only assigning part:
var DepartmentId = getITDepartment();
if (DepartmentId != null && DepartmentId.length > 0){
Xrm.Page.getAttribute("new_department").setValue([{
id: DepartmentId[0].new_departmentId,
name: "IT",
entityType: "new_department"
}]);
}
You are setting the lookup value correctly, you just need to get the Id correctly. The results variable is an array of new_department records, so try something like this:
var resultId = null;
XrmServiceToolkit.Rest.RetrieveMultiple("new_departmentSet", "$select=new_departmentId&$filter=new_name eq 'IT'",
function (results) {
if (results.length > 0)
resultId = results[0].new_departmentId; //gets the first record's Id
}, function (error) { alert(error); }, function onComplete() { }, false);
return resultId;

Categories