I have following code:
;(function($){
var getWeatherInfo = function(url, requiredKeys ) {
var info = {},
dfd = $.Deferred();
$.getJSON( url, function( data ) {
for(var i = 0; i < requiredKeys.length; i++) {
info[requiredKeys[i]] = data[requiredKeys[i]];
}
dfd.resolve(info);
});
return dfd.promise();
};
var url = 'http://api.openweathermap.org/data/2.5/weather?q=London,uk',
requiredData = [
'name',
'coord.lat',
'coord.lon',
'description'
];
getWeatherInfo(url,requiredData).done(function(data){console.log(data)});
The data output is:
Object {name: "London", coord.lat: undefined, coord.lon: undefined, description: undefined}
Name is working fine because it doesn't have . How can I fix rest? I don't want to use eval. Is there any better alternative?
This will work:
$.getJSON( url, function( data ) {
for(var i = 0; i < requiredKeys.length; i++) {
if (requiredKeys[i].indexOf('.') > -1){
var ar = requiredKeys[i].split("\.");
info[requiredKeys[i]] = data[ar[0]][ar[1]]
}
else{
info[requiredKeys[i]] = data[requiredKeys[i]];
}
}
dfd.resolve(info);
});
Result: Object {name: "London", coord.lat: 51.51, coord.lon: -0.13, description: undefined}
http://jsfiddle.net/gpzd9w43/
EDIT:
Maybe a more elegant way to do it if you have more than 1 dot:
$.getJSON( url, function( data ) {
for(var i = 0; i < requiredKeys.length; i++) {
var ar = requiredKeys[i].split("\.");
var node = data;
for (var j = 0; j < ar.length; j++){
node = node[ar[j]];
}
info[requiredKeys[i]] = node;
}
dfd.resolve(info);
});
http://jsfiddle.net/gpzd9w43/1/
Related
I'm trying to create a Parse cloud code function that returns the same result as a GET on parse/classes/MyClass but with the IDs of the relations.
I've done it for one object, but I can't make it work in a loop to get all the objects.
This is how I'm trying to get all the objects. It's working without the for loop and with r as a response.
Parse.Cloud.define('get_ClassName', function(request, response) {
let query = new Parse.Query('ClassName');
var ret = {};
query.find({useMasterKey: true}).then(function(results) {
for (var i = 0; i < results.length; i++) {
ret[i] = {};
const relQuery = results[i].get('status').query();
relQuery.find({useMasterKey: true}).then(function(res) {
var ids = {};
for (var j = 0; j < res.length; j++) {
ids[j] = res[j].id;
}
var status = {...status, id: ids};
status["className"] = "Status";
var r = {...r, status: status};
r["tag"] = results[i].get("tag");
ret[i] = r; //Can't access ret
//response.success(r); //Working
})
}
response.success(ret);
});
});
This is the actual result for the working version:
{
"result": {
"status": {
"id": {
"0": "xxxxxx",
"1": "xxxxxx"
},
"className": "Status"
},
"tag": "value"
}
}
response.success(ret); will run before relQuery.find finish in for loop.
Use Promise.all()
or Async await and refactor your logic.
I comment on your code about your missing.
Parse.Cloud.define('get_ClassName', function(request, response) {
let query = new Parse.Query('ClassName');
var ret = {};
query.find({useMasterKey: true}).then(function(results) { // Asyncronous
for (var i = 0; i < results.length; i++) {
ret[i] = {};
const relQuery = results[i].get('status').query();
relQuery.find({useMasterKey: true}).then(function(res) { // Asyncronous
var ids = {};
for (var j = 0; j < res.length; j++) {
ids[j] = res[j].id;
}
var status = {...status, id: ids};
status["className"] = "Status";
var r = {...r, status: status};
r["tag"] = results[i].get("tag");
ret[i] = r; //Can't access ret
//response.success(r); //Working
console.log(`index {i}`, r);
})
}
console.log(`response will be called`);
response.success(ret); // Called before `relQuery.find` finish
});
});
I have tried searching but can't find anything to help, maybe my problem is too simple! Anyway, I'm running an ajax request. The data given to the request is an array. Here is my code:
var id = "1#2#3#4#5#";
var chkdId = id.slice(0, -1);
var arr = chkdId.split('#');
var checkedId = '';
var chkdLen = arr.length;
for (var i = 0; i < chkdLen; i++) {
checkedId = arr[i];
var checkedId = checkedId;
var data = {};
var year = $('#year').val();
data["year"] = year;
data['type'] = "report";
data['accidentId'] = checkedId;
console.log(data);
ajax.readData('/report/readreport', data, null,
function (result) {
console.log(result);
},
function (error) {
alert('err ' + error);
}
);
}
request array:
Object {year:"2015" type: "report", accidentId: "1"}
Object {year:"2015" type: "report", accidentId: "2"}
Object {year:"2015" type: "report", accidentId: "3"}
Object {year:"2015" type: "report", accidentId: "4"}
Object {year:"2015" type: "report", accidentId: "5"}
result:
{"data":[{"name":aaaa,"age":"15"}]}
{"data":[{"name":bbb,"age":"25"}]}
{"data":[{"name":ccc,"age":"65"}]}
{"data":[{"name":ddd,"age":"45"}]}
{"data":[{"name":eee,"age":"24"}]}
How to store the results in a single array?
Here is my Solution
var id = "1#2#3#4#5#";
var chkdId = id.slice(0, -1);
console.log(chkdId);
var arr = chkdId.split('#');
var checkedId = '';
var chkdLen = arr.length;
// here is the array
var arrayWithResults = [];
for (var i = 0; i < chkdLen; i++) {
checkedId = arr[i];
var checkedId = checkedId;
var data = {};
var year = $('#year').val();
data["year"] = year;
data['type'] = "report";
data['accidentId'] = checkedId;
console.log(data);
ajax.readData('/report/readreport', data, null,
function (result) {
console.log(result);
// here you push in the requested data
arrayWithResults.push(result);
},
function (error) {
alert('err ' + error);
}
);
}
Take the ajax out of for. This will send only One ajax request to server and minimize the load on server.
var params = [];
for (var i = 0; i < chkdLen; i++) {
checkedId = arr[i];
var data = {};
var year = $('#year').val();
data["year"] = year;
data['type'] = "report";
data['accidentId'] = checkedId;
params.push(data);
// ^^^^^^^^^^^^^^
}
ajax.readData('/report/readreport', params, null,
// ^^^^^^
function (result) {
console.log(result);
},
function (error) {
alert('err ' + error);
}
);
I'm new to Angular and my experience with Javascript is not very extensive. I am failing to show data in ngGrid using following code. What is the problem?
In essence. I am loading data from a web-service, performing a transform (pivot) on it and then I want to present it in a grid.
Please see the following
app.js -> starting poing
var konstruktApp= angular.module('konstruktApp',['ngGrid']);
dataService.js -> web service call
'use strict';
konstruktApp.service('DataService',function DataService($http){
var callHttp = function(){
delete $http.defaults.headers.common['X-Requested-With'];
return $http.get("http://83.250.197.214/konstrukt.service/Konstrukt.SL.DummyBudgetService.svc/GetDummyBudgetData/");
};
return {
getDummyData: callHttp
};
});
ngGridController.js -> where the logic resides...
$scope.getData = DataService.getDummyData;
$scope.gridOptions = {data:'result'};
var getData = function() {
$scope.getData().then(function (response) {
var res = pivotData(response.data);
$scope.result = res.data.PivotedRows;
$scope.columns = res.cols;
console.log('from the success handler at ' + new Date());
}, function (reason) {
console.log('failed: ');
console.log(reason);
});
};
..and here is the logic that "pivots" the data
var pivotData = function(data) {
var firstColumn = "Dim1";
var secondColumn = "Period";
var columns = [];
columns.push({
field: firstColumn,
enableCellEdit: false
});
var pivotedArray = {};
pivotedArray.PivotedRows = [];
var rowItems = [];
var rowArray = {};
var previusFirstColumnValue = -1;
var firstColumnValue = 1;
//for each row
for (var i = 0; i < data.Rows.length; i = i + 1) {
//firstColumnValue = $scope.dataCollection.Rows[i].FindCell.Cells[firstColumn].Value;
firstColumnValue = findCell(data.Rows[i].Cells, firstColumn).Value;
//var secondColumnValue = data.Rows[i].Cells[secondColumn].Value;
var secondColumnValue = findCell(data.Rows[i].Cells, secondColumn).Value;
//if first column value has changed, add new row
if (firstColumnValue != previusFirstColumnValue) {
if (i !== 0) {
for (var j = 0; j < rowItems.length; j = j + 1) {
rowArray[rowItems[j].name] = rowItems[j].value;
}
pivotedArray.PivotedRows.push( rowArray);
rowArray = {};
rowItems = [];
}
rowItems.push({
name: firstColumn,
//value: $scope.dataCollection.Rows[i].Cells[firstColumn].Value
value: findCell(data.Rows[i].Cells, firstColumn).Value
});
}
//if (columns.indexOf({field: secondColumnValue}) == -1) {
if (i < 12) {
columns.push({
field: secondColumnValue,
editableCellTemplate: "<input ng-class=\"'colt' + col.index\" ng-input=\"COL_FIELD\" ng-blur=\"lostFocus()\" ng-model=\"COL_FIELD\" ng-change=\"dataChanged(col,row,row.entity)\"/>",
enableCellEdit: true
});
}
rowItems.push({
name: secondColumnValue,
value: findCell(data.Rows[i].Cells, secondColumn).Value
});
previusFirstColumnValue = firstColumnValue;
}
for (var k = 0; k < rowItems.length; k = k + 1) {
rowArray[rowItems[k].name] = rowItems[k].value;
}
// $scope.columns = columns;
pivotedArray.PivotedRows.push( rowArray);
return {data: pivotedArray, cols: columns};
};
plnkr: http://plnkr.co/edit/ZqC7696xGbUtuWGIvnYs?p=preview
EDIT: The data correlation rows<-> columns is correct, I suspect there is something wrong with data in the pivotedArray.PivotedRows array.
It turned out that moving the code to a new plnkr made the difference. Now, thats a few hours of my life that I want back :)
I have a html tag like this.
<a class="employee_details" target="_blank" href="index1.php?name=user1&id=123">User</a>
I need to get the two parameter values in jquery
<script type="text/javascript">
$(function () {
$('.employee_details').click(function () {
var status_id = $(this).attr('href').split('name');
alert(status_id[0]);
});
});
</script>
Any help in getting both the parameter values in two variables in javascript.
I want to get user1 and 123 in two variables using jQuery
Thanks
Kimz
You can use URLSearchParams as a most up-to-date and modern solution:
let href = $(this).attr('href');
let pars = new URLSearchParams(href.split("?")[1]);
console.log(pars.get('name'));
Supported in all modern browsers and no jQuery needed!
Original answer:
Try this logic:
var href = $(this).attr('href');
var result = {};
var pars = href.split("?")[1].split("&");
for (var i = 0; i < pars.length; i++)
{
var tmp = pars[i].split("=");
result[tmp[0]] = tmp[1];
}
console.log(result);
So you'll get the parameters as properties on result object, like:
var name = result.name;
var id = result.id;
Fiddle.
An implemented version:
var getParams = function(href)
{
var result = {};
var pars = href.split("?")[1].split("&");
for (var i = 0; i < pars.length; i++)
{
var tmp = pars[i].split("=");
result[tmp[0]] = tmp[1];
}
return result;
};
$('.employee_details').on('click', function (e) {
var params = getParams($(this).attr("href"));
console.log(params);
e.preventDefault();
return false;
});
Fiddle.
$(function() {
$('.employee_details').on("click",function(e) {
e.preventDefault(); // prevents default action
var status_id = $(this).attr('href');
var reg = /name=(\w+).id=(\w+)/g;
console.log(reg.exec(status_id)); // returns ["name=user1&id=123", "user1", "123"]
});
});
// [0] returns `name=user1&id=123`
// [1] returns `user1`
// [2] returns `123`
JSFiddle
NOTE: Better to use ON method instead of click
Not the most cross browser solution, but probably one of the shortest:
$('.employee_details').click(function() {
var params = this.href.split('?').pop().split(/\?|&/).reduce(function(prev, curr) {
var p = curr.split('=');
prev[p[0]] = p[1];
return prev;
}, {});
console.log(params);
});
Output:
Object {name: "user1", id: "123"}
If you need IE7-8 support this solution will not work, as there is not Array.reduce.
$(function () {
$('.employee_details').click(function () {
var query = $(this).attr('href').split('?')[1];
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
var varName = decodeURIComponent(pair[0]);
var varValue = decodeURIComponent(pair[1]);
if (varName == "name") {
alert("name = " + varValue);
} else if (varName == "id") {
alert("id = " + varValue);
}
}
});
});
It's not very elegant, but here it is!
var results = new Array();
var ref_array = $(".employee_details").attr("href").split('?');
if(ref_array && ref_array.length > 1) {
var query_array = ref_array[1].split('&');
if(query_array && query_array.length > 0) {
for(var i = 0;i < query_array.length; i++) {
results.push(query_array[i].split('=')[1]);
}
}
}
In results has the values. This should work for other kinds of url querys.
It's so simple
// function to parse url string
function getParam(url) {
var vars = [],hash;
var hashes = url.slice(url.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
// your code
$(function () {
$('.employee_details').click(function (e) {
e.preventDefault();
var qs = getParam($(this).attr('href'));
alert(qs["name"]);// user1
var status_id = $(this).attr('href').split('name');
});
});
I've Been using XSLT to display my xml page. I make use of the following to get the data from the xml file:
< xsl:value-of
select="ClinicalDocument/component/structuredBody/component[3]/section/text/table/tbody"/
>
After this, I have the following javascript to clean up the data and do the conversion:
-----------Get Content for Grids----------
//Split Content into array
var purposeArray = document.getElementById('purposeOfVisit').innerHTML.split("\n");
var activeProblemArray = document.getElementById('activeProblems').innerHTML.split("\n");
//------------ Remove All Unwanted Values-----------\\*/
var newDataString ="";
for( var k = 0; k < purposeArray.length; k++ )
{
newDataString += purposeArray[k] + "__";
}
newDataString = newDataString.replace(/ /g,"");
newDataString = newDataString.replace(/__________/g,"__-__");
var newDataArray = newDataString.split("__");
//------------- Save Values in final Array -------------\\*/
var semiFinalArray = new Array();
for( var x=0; x < newDataArray.length; x++)
{
if(newDataArray[x].length != 0)
{
semiFinalArray.push(newDataArray[x]);
}
}
var finalArray = new Array();
var counter = 0;
//------------ Find Number of Columns in row ------------\\*/
var numberOfRows = document.getElementById('numberOfRows').innerHTML;
var numberOfColumns = document.getElementById('numberOfColumns').innerHTML;
var columnsPerRow = parseInt(numberOfColumns) / parseInt(numberOfRows);
//------------------------------Testing ------------------------------//
var dataNamePre = "dataValue";
var temporaryArray = new Array();
var dataName;
//----------- Generate Grid Values -----------//
for( var b=0 ; b < semiFinalArray.length ; b = b + columnsPerRow)
{
var problemComment = "";
counter = 0;
var obj;
for( var a=0 ; a < columnsPerRow ; a++)
{
dataName = dataNamePre + counter.toString() + "";
//-------Generate Grid Titles------//
temporaryArray.push("Title " + (counter+1));
var key = "key"+a;
obj = { values : semiFinalArray[b+a] };
var problemComment = "";
finalArray.push(obj);
counter++;
}
}
//---------------------Generate GridArray---------------------------//
var gridArray = [];
var gridArrayHead = new Array();
counter = 0;
var objectValue = new Array();
for( var x = 0; x < finalArray.length; x++ )
{
objectValue = { head:temporaryArray[x], values: finalArray[x].values }
gridArray.push(objectValue);
}
var provFacilities = [];
for( var x = 0; x < finalArray.length; x++ )
{
provFacilities[x] =
{
head:temporaryArray[x], values: finalArray[x].values
}
}
//alert(gridArray);
$("#grid").kendoGrid(
{
columns:
[{
title:gridArray.head,
template:'#= values #'
}],
dataSource: {
data:finalArray,
pageSize:10
},
scrollable:false,
pageable:true
});
This may be a roundabout method, but I'm still prettry new to this method of coding.
Currently, all the data is being presented in one column, with the last value in my temporaryArray as the title for the column.
Everything works until I try to set the DataSource for the Kendo Grid. When working in the columns property in the grid, I made the following change:
title:gridArray[0].head
When this is done, the title is changed to the first value in the array.
What I want to know is how can I generate columns in the Kendo Grid According to the title? Is there a way to loop through all the values and create the objects from there, seeing that the date that is being sent to the grid are objects in an Array?
What I basically want is something to make this work, without the repitition:
var myGrid = $("#grid").kendoGrid( { columns: [ {
title: temporaryArray[0],
field: finalArray[0].values }, {
title: temporaryArray[1],
field: finalArray[1].values }, {
title: temporaryArray[2],
field: finalArray[2].values }, {
title: temporaryArray[3],
field: finalArray[3].values }, {
title: temporaryArray[4],
field: finalArray[4].values } ]
)};
Any help appreciated, thanks!
This issue has been fixed using the following coding:
var arrayData = [];
for( var x = 0; x < semiFinalArray.length; x=x+5 )
{
var tempArr = new Array();
for( var y = 0; y < 5; y++ )
{
var num = x + y;
tempArr.push(semiFinalArray[num]);
}
arrayData.push(tempArr);
}
var dataTitles = [];
for( var x = 0; x < titleArray.length; x++ )
{
var head = "";
head = titleArray[x];
head = head.replace(/ /g,"");
dataTitles.push(head);
}
var counter = 0;
var columnDefs = [];
for (var i = 0; i < columnsPerRow.length; i++)
{
if (counter == (columnsPerRow - 1))
{
counter = 0;
}
columnDefs.push({ field: dataTitles[counter], template: arrayData[i].values });
counter++;
}
// Create final version of grid array
var gridArray = [];
for (var i = 0; i < arrayData.length; i++)
{
var data = {};
for (var j = 0; j < dataTitles.length; j++)
{
data[dataTitles[j]] = arrayData[i][j];
}
gridArray.push(data);
}
// Now, create the grid using columnDefs as argument
$("#grid").kendoGrid(
{
dataSource:
{
data: gridArray,
pageSize: 10
},
columns: columnDefs,
scrollable: false,
pageable: true
}).data("kendoGrid");
With this, the data is displayed in the DataGrid.