How do access a json object 0 using a javascript - javascript

I pretend to do console.log of the holidays variable appear in the list and not as an array. How do I get this information as a simple object?
My json:
[{
"2016-10-10":[{"name":"Columbus Day","country":"US","date":"2016-10-10"}],
"2016-10-31":[{"name":"Halloween","country":"US","date":"2016-10-31"}]
}]
My app:
app.factory('calendario', function($http) {
return{
getJobs : function() {
return $http({
url: '/app/components/home/controller/test_calendar.json',
method: 'GET'
})
}
}
});
controller:
var holidays = [];
calendario.getJobs().success(function(data){
holidays.push(data[0]);
});
$scope.setDayContent = function(date) {
console.log(holidays);
};
Example:
I want this
I don't want this

You want to flatten it, so, Nick is right, do not use the array, use dict/hash instead. In case your functionality will suffer you can use some workaround:
var holidays = [{
"2016-10-10":[{"name":"Columbus Day","country":"US","date":"2016-10-10"}],
"2016-10-31":[{"name":"Halloween","country":"US","date":"2016-10-31"}]
}];
var flatten_holidays = holidays.reduce(function(elem){return elem});
I do not feel like it is specifically AngularJS question, more like common JavaScript instead.
For your example it would be:
var holidays = [];
calendario.getJobs().success(function(data){
holidays.push(data[0]);
});
$scope.setDayContent = function(date) {
console.log(holidays.reduce(function(elem){return elem}));
};
or, if the preference is to use dict/hash:
var holidays = {};
calendario.getJobs().success(function(data){
//if data is: {"2016-10-10":[{"name":"Columbus day","country":"US","date":"2016-10-10"}]}
var key = Object.keys(data)[0];
var value = data[key];
holidays[key] = value;
});
$scope.setDayContent = function(date) {
console.log(holidays);
};

This question is to easy ... no?
var holidays = [];
calendario.getJobs().success(function(data){
holidays=data[0];
});
$scope.setDayContent = function(date) {
console.log(holidays);
};

Instead of a list use a map
holidays = {}
Then put the items in the map with key the date and value the array:
holidays[data[0].date] = data[0].days;
But it looks like you already have the map, so probably you can just save data directly instead of pushing it in a list:
var holidays = {};
calendario.getJobs().success(function(data){
holidays=data;
});
$scope.setDayContent = function(date) {
console.log(holidays);
};

Related

How to update JavaScript array dynamically

I have an empty javascript array(matrix) that I created to achieve refresh of divs. I created a function to dynamically put data in it. Then I created a function to update the Array (which I have issues).
The Data populated in the Array are data attributes that I put in a JSON file.
To better undertand, here are my data attributes which i put in json file:
var currentAge = $(this).data("age");
var currentDate = $(this).data("date");
var currentFullName = $(this).data("fullname");
var currentIDPerson = $(this).data("idPerson");
var currentGender = $(this).data("gender");
Creation of the array:
var arrayData = [];
Here is the function a created to initiate and addind element to the Array :
function initMatrix(p_currentIDPerson, p_currentGender, p_currentFullName, p_currentDate, p_currentAge) {
var isFound = false;
// search if the unique index match the ID of the HTML one
for (var i = 0; i < arrayData.length; i++) {
if(arrayData[i].idPerson== p_currentIDPerson) {
isFound = true;
}
}
// If it doesn't exist we add elements
if(isFound == false) {
var tempArray = [
{
currentIDPerson: p_currentIDPerson,
currentGender: p_currentGender,
currentFullName: p_currentFullName,
currentDate: p_currentDate, currentAge: p_currentAge
}
];
arrayData.push(tempArray);
}
}
The update function here is what I tried, but it doesn't work, maybe I'm not coding it the right way. If you can help please.
function updateMatrix(p_currentIDPerson, p_currentGender, p_currentFullName, p_currentDate, p_currentAge) {
for (var i = 0; i < arguments.length; i++) {
for (var key in arguments[i]) {
arrayData[i] = arguments[i][key];
}
}
}
To understand the '$this' and elm: elm is the clickableDivs where I put click event:
(function( $ ) {
// Plugin to manage clickable divs
$.fn.infoClickable = function() {
this.each(function() {
var elm = $( this );
//Call init function
initMatrixRefresh(elm.attr("idPerson"), elm.data("gender"), elm.data("fullname"), elm.data("date"), elm.data("age"));
//call function update
updateMatrix("idTest", "Alarme", "none", "10-02-17 08:20", 10);
// Définition de l'evenement click
elm.on("click", function(){});
});
}
$('.clickableDiv').infoClickable();
}( jQuery ));
Thank you in advance
Well... I would recommend you to use an object in which each key is a person id for keeping this list, instead of an array. This way you can write cleaner code that achieves the same results but with improved performance. For example:
var myDataCollection = {};
function initMatrix(p_currentIDPerson, p_currentGender, p_currentFullName, p_currentDate, p_currentAge) {
if (!myDataCollection[p_currentIDPerson]) {
myDataCollection[p_currentIDPerson] = {
currentIDPerson: p_currentIDPerson,
currentGender: p_currentGender,
currentFullName: p_currentFullName,
currentDate: p_currentDate,
currentAge: p_currentAge
};
}
}
function updateMatrix(p_currentIDPerson, p_currentGender, p_currentFullName, p_currentDate, p_currentAge) {
if (myDataCollection[p_currentIDPerson]) {
myDataCollection[p_currentIDPerson] = {
currentGender: p_currentGender,
currentFullName: p_currentFullName,
currentDate: p_currentDate,
currentAge: p_currentAge
};
}
}
Depending on your business logic, you can remove the if statements and keep only one function that adds the object when there is no object with the specified id and updates the object when there is one.
I think the shape of the resulting matrix is different than you think. Specifically, the matrix after init looks like [ [ {id, ...} ] ]. Your update function isn't looping enough. It seems like you are trying to create a data structure for storing and updating a list of users. I would recommend a flat list or an object indexed by userID since thats your lookup.
var userStorage = {}
// add/update users
userStorage[id] = {id:u_id};
// list of users
var users = Object.keys(users);

How to convert object key dot notation to object tree in javascript

I have a form and I want to send it to an ajax endpoint, for this I have this helper method:
$.fn.serializeFormToObject = function() {
//serialize to array
var data = $(this).serializeArray();
//add also disabled items
$(':disabled[name]', this)
.each(function() {
data.push({ name: this.name, value: $(this).val() });
});
//map to object
var obj = {};
data.map(function(x) { obj[x.name] = x.value; });
return obj;
};
The problem is that I have dot notation in some of the names of my form (using MVC strong typed model)
So I have this object as result:
Task.Addresses.Box:""
Task.Addresses.City:"Limal"
Task.Addresses.Country:"Belgique"
Task.Deadline:"1/10/2017 12:18:18 PM"
Task.TaskSourceId:"1"
And the result expected would be:
{ Task : { Addresses: { Box: "", City: "Limal", Country: "Belgique"}, Deadline: "1/10/2017 12:18:18 PM", TaskSourceId:"1" } }
I use the lodash library but after some hours I cannot find a way to do this expected result.
Can someone provide me a working javascript helper to give the expected nested object?
Edit:
For duplicated question, the other question does not ask about combined nested object together
After the answer of #ori-drori, This code is working as expected:
$.fn.serializeFormToObject = function() {
//serialize to array
var data = $(this).serializeArray();
//add also disabled items
$(':disabled[name]', this)
.each(function() {
data.push({ name: this.name, value: $(this).val() });
});
//map to object
var obj = {};
data.map(function (x) { obj[x.name] = x.value; });
var objNested = {};
_.forEach(obj, function (value, key) { _.set(objNested, key, value) });
return objNested;
};
Iterate the data using Array#forEach, and assign the value to the path (name) using _.set():
data.forEach(function(x) { _.set(obj, x.name, x.value) });
I don't have you're original data, so here is a demo using the key-values you provided.
var fields = {
"Task.Addresses.Box": "",
"Task.Addresses.City": "Limal",
"Task.Addresses.Country": "Belgique",
"Task.Deadline": "1/10/2017 12:18:18 PM",
"Task.TaskSourceId": "1"
};
var obj = {};
_.forEach(fields, function(value, key) {
_.set(obj, key, value);
});
console.log(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

How can I adjust this .when that does getJSON to return results ordered by date?

UPDATE: Looks like we're headed for a bounty. First time ever for me.
My goal is to adjust this code to get results ordered by date.
CODE SAMPLE
$.when( $.getJSON(url0), $.getJSON(url1), $.getJSON(url2), $.getJSON(url3),$.getJSON(url4), $.getJSON(url5),$.getJSON(url6),$.getJSON(url7) ).done( function() {
$.each(arguments, function(index, result) {
var data = result[0];
utcday = data[0].createdOn;
ltrDay = moment.utc(utcday).format("DD MMM YY");
console.log(ltrDay);
});
});
This code returns the results ordered by the getJSON url I'm calling.
It is the desired behavior in most cases.
However, I now need to return the results ordered by date too for other cases (descending order, newest first).
You have the results inside your when, now you just need to sort using a standard sort function.
$.when( $.getJSON(url0), $.getJSON(url1), $.getJSON(url2), $.getJSON(url3),$.getJSON(url4), $.getJSON(url5),$.getJSON(url6),$.getJSON(url7) ).done( function() {
var results = args = Array.prototype.slice.call(arguments);
args.sort(function(a, b) {
return a[0][0].createdOn - b[0][0].createdOn;
});
// use sorted args now, args are the results
console.log(results);
// assuming a modern browser and using forEach
results.forEach(function(result) {
console.log(result[0][0].createdOn);
});
});
Maybe I'm missing something? But you should be able to use your results which should now be sorted by the createdOn property. I'm assuming your createdOn property is already a date object.
Make sure you echo json_encode($assocArray) the proper JSON, which will go into the data arguments you see below. This way when they are done the variables above $.when() will have the data I believe you want as your arguments Array Like Object.
var u0, u1, u2, u3, u4, u5, u6, u7;
$.when($.getJSON(url0, function(data){u0 = data}), $.getJSON(url1, function(data){u1 = data}), $.getJSON(url2, function(data){u2 = data}), $.getJSON(url3, function(data){u3 = data}), $.getJSON(url4, function(data){u4 = data}), $.getJSON(url5, function(data){u5 = data}), $.getJSON(url6, function(data){u6 = data}), $.getJSON(url7, function(data){u7 = data})).done(function(){
var arrayOfObjects = [];
$.each([u0, u1, u2, u3, u4, u5, u6, u7], function(index, result){
var rz = result[0];
arrayOfObjects.push({data:rz, utcday:rz.data[0].createdOn, ltrDay:moment.utc(utcday).format('DD MM YY')});
});
function youMakeIt(aryObs){
var dateArray = [];
$.each(aryObs, function(i, v){
dateArray.push(v.ltrDay);
});
/* now you do your thing with `dateArray` putting the array of indexes in
an `indexes` variable to get the `arrayOfObjects` in the order you like
Next its like */
var solution = [];
$.each(indexes, function(i, v){
solution.push(dateArray[v]);
});
// solution Array holds the order you want for your Objects
return solution;
}
var newArrayOfObjects = youMakeIt(arrayOfObjects);
});
Unless the URLs you are making request to that serve up the JSON accept parameters to sort by date, you'll have to do it after you have all the data. Something like this should work
var date_sort_desc = function (date1, date2) {
if (date1 > date2) return -1;
if (date1 < date2) return 1;
return 0;
};
var dates = [];
$.when( $.getJSON(url0), $.getJSON(url1), ... ).done( function() {
$.each(arguments, function (index, result) {
var data = result[0];
var utcday = data[0].createdOn;
dates.push(moment.utc(utcday).format("YY MM DD"));
});
dates.sort(date_sort_desc);
});

Format returned table data in json

I'm fairly new to javascript. I retreive data from a sql server database that looks like this :
[Object { shortcode="0013A2004031AC9A", latest_measurement=1067, keyid="6801"},
Object { shortcode="0013A2004031AC9A", latest_measurement=7, keyid="6802"},
Object { shortcode="0013A2004031AC9A", latest_measurement=8598838, keyid="6803"}]
I want to format this in a json like this :
{mac : 0013A2004031AC9A, keys : {6801:1067, 6802:7, 6803:8598838}}
but I just don't get to that.
I have
var jsonDataPerMac = {};
I loop over the json object above and for every new mac I find I do :
jsonDataPerMac[i]={"mac": device.shortcode, "keys":[]};
but how do I get to fill the keys?
Any hints would be appreciated.enter code here
var macs = [];
var jsonDataPerMac = {};
var i = 0;
$.ajax({
url: "/bmmeasurements",
type: "GET",
data: {"unitid" : unitid},
async: false,
success: function (data) {
console.log(data);
initializeTable();
$.each(data, function (index,device) {
//add all distinct macs in an array, to use them as a column header
if($.inArray(device.shortcode, macs) == -1) {
macs.push(device.shortcode);
jsonDataPerMac[i]={"mac": device.shortcode, "keys":[]};
i++;
//create a table cell for each possible key. id = 'mac-key'
createTableGrid(device.shortcode);
}
//add the measurement data to the correct cell in the grid
$('#' + device.shortcode + '-' + device.keyid).html(device.latest_measurement);
});
}});
Here is my proposition. I would rather avoid using jQuery to perform such a simple operations. In this particular example, we use forEach and for..in loop.
//new output array
var newArray = [];
//we traverse the array received from AJAX call
array.forEach(function(el) {
var added = false; // it's false by default
// we check if the mac is already in newArray, if yes - just add the key
for(var i in newArray) {
if(newArray[i].mac == el.shortcode) {
newArray[i].keys.push(el.keyid+":"+el.latest_measurement);
added = true; // tells us whether the key has been added or not
}
}
// if key hasn't been added - create a new entry
if(!added) {
newArray.push({"mac": el.shortcode, "keys":[el.keyid+":"+el.latest_measurement]});
}
});
console.log(newArray);
You can transform above code to a function and then, reuse it in your ajax onSuccess method. Remember to pass the array as an argument and to return newArray.
JSFiddle:
http://jsfiddle.net/2d5Vq/2/
You need to combine the entries first...
var reducedData = {};
$.each(macs, function(index,macitem){
if (reducedData.hasOwnProperty(macitem.shortcode)) {
reducedData[macitem.shortcode].push(macitem.key);
} else {
reducedData[macitem.shortcode] = [ macitem.key ];
}
});
And then map to your desired format inside an array...
var jsonDataPerMac = [],
i = 0;
$.map(reducedData, function(keys,mac){
jsonDataPerMac[i++] = {"mac": mac, "keys": keys};
// your other code goes here
});
Also your usage of jsonDataPerMac suggests that you want it to be an array.

nested for loop in javascript knockout

I have two observable arrays:
var viewModel = {
PositionTypes: ko.observableArray([]),
Users: ko.observableArray([])
}
POSITION ViewModel
var positionViewModel = function (data) {
var _self = this;
_self.PositionName = ko.observable(data.PositionName);
_self.PositionRank = ko.observable(data.PositionRank);
_self.ContentRole = ko.observable(data.ContentRole);
}
positionViewModel.AddPositions = function (data) {
$.each(data, function (index, value) {
positionViewModel.PushPosition(value);
});
};
positionViewModel.PushPosition = function (postion) {
viewModel.PositionTypes.push(new positionViewModel(position));
};
USER ViewModel
// the ViewModel for a single User
var userViewModel = function (data) {
var _self = this;
_self.ID = ko.observable(data.ID);
_self.Name = ko.observable(data.Name);
_self.Email = ko.observable(data.Email);
_self.ContentRole = ko.observable(data.ContentRole);
};
userViewModel.AddUsers = function (data) {
$.each(data, function (index, value) {
userViewModel.PushUser(value);
});
};
userViewModel.PushUser = function (user) {
viewModel.Users.push(new userViewModel(user));
};
How can i using linq.js so that i could loop through every position so i could get all the users for each position?
foreach( each position in positions)
{
foreach(each user in users)
{ list of users for the position}
}
You could also use ko.utils.arrayForEach as follow :
ko.utils.arrayForEach(viewModel.PositionTypes(), function(position){
var usersInPosition = ko.utils.arrayFilter(viewModel.Users(), function(user){
return user.ContentRole() == position.ContentRole();
});
ko.utils.arrayForEach(usersInPosition, function(user){
});
});
See doc
I hope it helps.
Using linq.js, you can perform a join on the columns you want to compare.
Assuming you are joining between the ContentRoles:
var query = Enumerable.From(viewModel.PositionTypes())
.GroupJoin(viewModel.Users(),
"$.ContentRole()", // position selector
"$.ContentRole()", // user selector
"{ Position: $, Users: $$.ToArray() }")
.ToArray();
So I think you want to create an object that contains a mapping of all the positions and user names. You can create such an object using the Aggregate() function to collect all the results into a single object.
var userPositions = Enumerable.From(this.PositionTypes())
.GroupJoin(this.Users(),
"$.ContentRole()", // position selector
"$.ContentRole()", // user selector
"{ Position: $, Users: $$ }") // group all users per position
.Aggregate(
{}, // start with an empty object
function (userPositions, x) {
var positionName = x.Position.PositionName(),
userNames = x.Users.Select("$.Name()").ToArray();
// add the new property
userPositions[positionName] = userNames;
return userPositions;
}
);

Categories

Resources