slice D3 update - arrays

I have created a dynamic dropdown who enables to select a country name to see data for this country. When a country is selected a function is invoked that will update the chart with data for this country.
It works well unless I select a country I have already previously selected, in which case I have the following error message:
"Uncaught TypeError: t.slice is not a function"
The dropdown is created and updated with the following code
var countryList = d3.map();
data.forEach(function(d) {
countryList.set(d.country,d.country); });
var select = d3.select(dropdown)
.selectAll("option")
.data(countryList.values().sort())
.enter().append("option")
.attr("value", function(d) {
return [d]; })
.text(function(d) { return [d]; });
d3.selectAll("select")
.on("change",function(){
var selectedCountry = document.getElementById("dropdown");
selectedCountry.options[selectedCountry.options.selectedIndex].selected = true;
var countryName = countryList.get(this.value)
//Calling the function countryChart
countryChart(data,countryName);
});
The function starts with the following code
function countryChart(data,countryName){
dataCou=data.filter(function(d) {
return(d.country == countryName)});
dataCou.forEach(function(d) {
d.monthYear = format.parse(d.monthYear);
d.count =+ d.count;
});
The part of the code that seems to be causing some problem is:
dataCou.forEach(function(d) {
d.monthYear = format.parse(d.monthYear);
d.count =+ d.count;
});
My data are formatted this way:
highest,monthYear,count,country
Community,2011-05-01,1116,Total
Community,2011-06-01,338,Total
Community,2011-07-01,56,Total
Community,2011-08-01,46,Total
Community,2011-09-01,52,Total
Community,2011-10-01,137,Total
Education,2011-05-01,1116,Total
Education,2011-06-01,338,Total
Education,2011-07-01,56,Total
Education,2011-08-01,46,Total
Education,2011-09-01,52,Total
Education,2011-10-01,137,Total
Community,2011-05-01,1116,USA
Community,2011-06-01,338,USA
Community,2011-07-01,56,USA
Community,2011-08-01,46,USA
Community,2011-09-01,52,USA
Community,2011-10-01,137,USA
Education,2011-05-01,1116,USA
Education,2011-06-01,338,USA
Education,2011-07-01,56,USA
Education,2011-08-01,46,USA
Education,2011-09-01,52,USA
Education,2011-10-01,137,USA
Do you have any idea what it is I am doing wrong?

Your d.monthYear is the number for some reason, but must be a string.
d.monthYear = format.parse(d.monthYear); // <-- here is the problem
When I do d3.time.format("%Y-%m-%d").parse(5), I get Uncaught TypeError: t.slice is not a function(…)
But when I do d3.time.format("%Y-%m-%d").parse('2011-05-01'), I get Sun May 01 2011 00:00:00 GMT-0700 (Pacific Daylight Time)

Related

Rendering Date from model in react

I am trying to get the date to render in a nice format. currently rendering like this
I tried
function getEndDateFromstring(){
return itinerary.endDate.split('T').slice(-1)[0]
}
then
{itinerary.name} from {getStartDateFromstring()} to {getEndDateFromstring()}
But it is throwing an error
Uncaught TypeError: Cannot read properties of undefined (reading 'split')
This looks like a scope issue, pass the itinerary to your function like below
function getEndDateFromstring(itinerary){
return itinerary.endDate.split('T').slice(-1)[0]
}
and call like
{itinerary.name} from {getStartDateFromstring(itinerary)} to {getEndDateFromstring(itinerary)}
I got it working with this
function addZeroIfOnlyOneChar(dateString){
dateString = String(dateString);
if(dateString.length < 2){
return '0' + dateString
}
return dateString
}
function getDateFromString(dateString){
const date = new Date(dateString)
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();
return `${addZeroIfOnlyOneChar(day)}-${addZeroIfOnlyOneChar(month)}-${year}`
}
Thanks Everyone

How to get specific month on AngularJS

How can I get the specific date month coming from the backend on angularJS
I wish to add something like this:
var curMonth = new Date().getMonth();
var monthData = vm.paymentsData[0].date.Date().getMonth();
if (curMonth == monthData) {
console.log ("Same Month");
}
Im getting error on:
var monthData = vm.paymentsData[0].date.Date().getMonth();
it says:
angular.js:14328 TypeError: vm.paymentsData[0].date.Date is not a function
Thanks
Data from the backend
I think your code should be written as follows:
var curMonth = new Date().getMonth();
// this maybe a string .. and you cannot call Date() function in that way.
var monthData = vm.paymentsData[0].date;
// Date function should be called this way.
var monData = (new Date(monthData)).getMonth();
if (curMonth == monData) {
console.log ("Same Month");
}

angularjs reinitializing arrays gives me "TypeError: Cannot read property 'push' of undefined"

I am running into a peculiar problem.
I have a my view of drop down list as this in HTML:
<div ng-controller='ConfigurableInputController as configurableInput'>
<select class="fixed-input"
ng-model="configurableInput.selectedCriteria"
ng-change="configurableInput.update()"
ng-options="criterion.selected as criterion.name for criterion in configurableInput.criteriaList">
<option value="">--Please select the comparison criteria--</option>
</select>
The above shows me 3 options in drop down list: Store, Channel and Permissions.
When ever I change the option from Store to Channel or Permissions or any combination the view changes (input boxes, certain labels etc.)
My update() method in controller does this:
configurableInput.update = function () {
configurableInput.permission = "";
configurableInput.id1 = "";
configurableInput.id2 = "";
configurableInput.items1 = "";
configurableInput.items2 = "";
configurableInput.defaultValueArray = [];
configurableInput.permissionsArr = [];
}
On selection of the drop down item, I do a ng-click on a button which retrieves information from Db.
There are 2 flavors of methods which are called on ng-click but the one giving me trouble is this one in the Service method:
StoreConfigurableService.$inject = ['$q', '$http', 'ApiBasePath'];
function ConfigurableService($q, $http, ApiBasePath) {
var service = this;
var defaultValueArr = [];
var permissionsArr = [];
var items1 = "";
var items2 = "";
service.retrievePermissions = function (criterion, id1, id2, rlNumber1, rlNumber2) {
$q.all([
$http.get(ApiBasePath + "/" + criterion + "/" + id1 + "/" + rlNumber1),
$http.get(ApiBasePath + "/" + criterion + "/" + id2 + "/" + rlNumber2)
])
.then(function (response) {
items1 = response[0].data;
items2 = response[1].data;
if (criterion === 'Permissions') {
var processed = false;
permissionsArr = makePermissionsArray(permissionsArr, items1, items2, processed);
}
})
.catch(function (errorResponse) {
console.log("Error: " + errorResponse);
throw errorResponse;
});
};
... so on
In my makePermissionsArray() I am doing this:
function makePermissionsArray(arr, items1, items2, processed) {
var map = items1.storePermissions;
var map2 = items2.storePermissions;
var map3 = items1.allPermissions;
for (var key in map) {
arr.push({
'code': key,
'description': map3[key],
'repStorePermission1': map[key],
'repStorePermission2': map2[key]
});
}
}
I get this permissionsArr back to controller through this:
service.getPermissionsArr = function () {
return permissionsArr;
};
NOTE that 'arr' in the argument of method makePermissionsArray() is not initialized because I am getting it by passing permissionsArr in the argument.
Now how the flow goes is:
First I select Store from drop down list, click on button to retrieves configurables for the store. This gives me correct response.
Then I select 'Permissions' from drop down list, click on button to retrieve permission configurables from Db, it gets stuck and does not get me any response.
I thought I am not clearing the arrays correctly in update() method and after some long search I found and changed these array initializing from:
configurableInput.defaultValueArray = [];
configurableInput.permissionsArr = [];
to
configurableInput.defaultValueArray.length = 0;
configurableInput.permissionsArr.length = 0;
in my update() method.
Now what happens is this:
First I select Store from drop down list, click on button to retrieves configurables for the store. This gives me correct response.
Then I select 'Permissions' from drop down list, click on button to retrieves permission configurables from Db, it gives me correct response.
I select Store from drop down list again, click on button and I get correct response.
But when I again select 'Permissions' from drop down list, click on button, it gives me this error - TypeError: Cannot read property 'push' of undefined
Error I get is at this point:
arr.push({
'code': key,
'description': map3[key],
'repStorePermission1': map[key],
'repStorePermission2': map2[key]
});
I am literally tearing my hair out because of this problem. Can someone please help me what's wrong?

Extending $firebaseArray with an extended $firebaseObject

Trying to cut down code repetition, I've set up a $firebaseArray extension as follows:
var listUsersFactory = $firebaseArray.$extend({
$$added: function (snap) {
return new Customer(snap);
},
$$updated: function (snap) {
var c = this.$getRecord(snap.key);
var updated = c.updated(snap);
return updated;
},
});
and the Customer code:
function Customer(snap) {
this.$id = snap.key;
this.updated(snap);
}
Customer.prototype = {
updated: function(snap) {
var oldData = angular.extend({}, this.data);
this.data = snap.val();
// checks and such
}
}
This works wonders when loading, showing and saving a list of customers, and I'm satisfied with it.
Now, the problem lies in retrieving a single customer and its detail page, because the Customer object isn't an extension of $fireObject and is therefore lacking a $save method
Single customer loading:
customersRef.once("value", function(snapshot) {
if(snapshot.child(uuid).exists())
{
customersFactory.customerDetails = new Customer(snapshot.child(uuid));
return deferred.resolve();
}
}
but when I call customersFactory.customerDetails.$save() I get an error
How can I extend my class so that it works for both array and single object uses?
I couldn't find a way to do this, so I ended up using the $firebaseArray and getting single records off that to pass as details, in case anyone's wondering

Angular JS object scope

I have written a simple Angular JS code which greets user depending on the time of the day. It works fine. The code is given below:
var modSvc = angular.module("appName",[]);
modSvc.provider("date",function(){
var greeting;
return {
showGreeting:function(value){
greeting = value;
},
$get:function(){
//it has to return an object which can have variables and functions
return {
showDate:function(){
var date = new Date();
return date.getHours();
},
showGreetingMessage:function(){
//var date = new Date();
return greeting + ", It's "+ this.showDate();
}
}
}
};
});
modSvc.config(function(dateProvider){
var hours = dateProvider.$get().showDate();
if(hours<12)
dateProvider.showGreeting("Good morning!");
else if(hours<17)
dateProvider.showGreeting("Good afternoon!");
else if(hours<22)
dateProvider.showGreeting("Good evening!");
else
dateProvider.showGreeting("Good night!");
});
function serviceController($scope,date){
$scope.greetingMessage = date.showGreetingMessage();
}
modSvc.controller("svcController",serviceController);
If you see showGreetingMessage function it has only one line of code which is:
return greeting + ", It's "+ this.showDate();
However showDate function resides at the same level as that of showGreetingMessage function. That's why this.showDate should not work and it should give error. But it works perfectly fine. How is it so?
It depends on the JavaScript engine that is used but according to the Mozilla reference your "this" actually references the parent object since you are returning an object.
As an object method
When a function is called as a method of an object, its this is set to the object the method is called on.
In the following example, when o.f() is invoked, inside the function this is bound to the o object.
var o = {
prop: 37,
f: function() {
return this.prop;
}
};
console.log(o.f()); // logs 37

Resources