trouble with OOP functions - javascript - javascript

I'm developing a datepicker using pure javascript. The datepicker works fine, but i have a problem that i dont know how to solve:
I have this line:
var my_cal = new Calendar("cal","2020-01-1","2022-01-01","2021-06-14");
that declare the Calendar object. Among the variables of the object, there are 2 variables whose value is the picked dates:
this.FromDate=null;
this.ToDate=null;
Also,there is a function that executes when the user clicks on one of the dates in the calendar, and the function according to the conditions, defines the two variables I mentioned above.
this.date_pick=function()
{
if(my_cal.FromDate==null){
my_cal.FromDate=new Date(this.getAttribute("data-date"));
console.log("From Date "+my_cal.FromDate);
}
else {
if(my_cal.ToDate==null){
let todate=new Date(this.getAttribute("data-date"));
if(todate>my_cal.FromDate){
my_cal.ToDate=new Date(this.getAttribute("data-date"));
console.log("To Date "+my_cal.ToDate);
}
}
else {
my_cal.FromDate=new Date(this.getAttribute("data-date"));
console.log("From Date "+my_cal.FromDate);
my_cal.ToDate=null;
}
}
my_cal.create();
};
The problem is that I need to call directly to the my_cal variable to make the function work, and I want it to work for each calendar individually created by the page.
I tried to change the my_cal. to this., like that:
this.date_pick=function()
{
if(this.FromDate==null){
this.FromDate=new Date(this.getAttribute("data-date"));
console.log("From Date "+this.FromDate);
}
else {
if(this.ToDate==null){
let todate=new Date(this.getAttribute("data-date"));
if(todate>this.FromDate){
this.ToDate=new Date(this.getAttribute("data-date"));
console.log("To Date "+this.ToDate);
}
}
else {
this.FromDate=new Date(this.getAttribute("data-date"));
console.log("From Date "+this.FromDate);
this.ToDate=null;
}
}
this.create();
};
but I get this error:
Uncaught TypeError: this.create is not a function
at HTMLTableCellElement.Calendar.date_pick
and I really dont know what to do.
codepen for the whole project: https://codepen.io/DavidiAllove/pen/YzZMgGg
Thanks for the helpers !! :)
EDIT:
I changed the self to this, I get the same error.

Related

Automatically add method at the end of method chain

I'm building a JavaScript class and I would like to return a result at the end of a method chain without calling a specific method.
Example 1: myDate('01/01/2000').add(1, 'day') should return 01/02/2000.
Example 2: myDate('01/01/2000').add(1, 'day').format('MMMM D YYYY') should return January 2 2000.
I know that this is possible using a JS class because saw it working in DayJs, I just don't understand how: https://github.com/iamkun/dayjs/blob/dev/src/index.js#L77
For now, what I have looks like this:
class MyDate {
constructor(date) {
this.date = date;
}
add(count, unit) {
this.date = // function
return this; // to enable method chaining
}
format() {
this.date = // function
return this.date; // to return the desired result
}
get() {
return this.date;
}
}
// wrapper function to instantiate class on function call
const myDate = date => new MyDate(date);
With this setup, I get the following behavior:
Example 3: myDate('01/01/2000').add(1, 'day') returns { date: 01/02/2000} instead of 01/02/2000.
Example 4: myDate('01/01/2000').add(1, 'day').format('MMMM D YYYY') returns January 2 2000 as expected.
Example 5: myDate('01/01/2000').add(1, 'day').get() returns 01/02/2000 but there is that nagging get() that I would like to eliminate...
I googled the issue, "js detect end of method chain" and such, but I couldn't find any results that would explain how this works.
Thanks for your help!
Logically speaking add method on a class should return the object instance instead of a particular member variable.
What you have as of now is perfect and that's how any user would expect it to work.
Imagine a case where you had to add another member variable, say time to your class and you want to chain something like object.add(1, 'day').add(5, 'hour'). You can achieve this only if your add function returns an instance of your class.
It is also perfectly fine to have to attach a get() method at the end. Consider the famous moment.js package. Even they have a format() method to get the actual date object.
Hope this clarifies your confusion.
Looking back at it, what I wanted to do was a class that had the following features:
import myDate from "./myDate.js"
import { isMyDate } from "./myDate.js"
No need to use the new keyword to instantiate
Can pass an unlimited number of arguments
With function chaining
console.log(myDate(params)) outputs a custom string MyDate<date_in_ms)>
${myDate(params)} outputs a custom string date_in_ms
Here is a possible implementation of it:
// Custom console.log
// Deno: https://doc.deno.land/builtin/stable#Deno.inspect
const inspect = Symbol.for("Deno.customInspect")
// Node: https://nodejs.org/api/util.html#util_util_inspect_custom
// const inspect = Symbol.for('nodejs.util.inspect.custom');
class MyDate {
constructor(date = new Date(), options) {
// Set the class's properties
this._date = date;
this._options = options;
// Run initialization tasks
this.initialize();
}
initialize() {
// if Date, convert time to milliseconds
if (this._date instanceof Date) {
this._date = this._date.getTime();
}
}
// Output the result
format() {
return this._date;
}
// Chainable function
add(amount) {
this._date += amount;
return this;
}
// Output all the parameters past after the first one
options() {
return this._options;
}
// Custom console.log
[inspect]() {
return `MyDate<${this._date}>`;
}
// Custom String output
toString() {
return `${this._date}`;
}
}
// Automatically instantiate class
const myDate = (date, ...options) => {
return new MyDate(date, options);
}
// Stand-alone function
const isMyDate = date => date instanceof MyDate;
// Access the stand-alone funtion from the MyDate instance
myDate.isMyDate = date => isMyDate(date);
export default myDate;
export { isMyDate };
Link to Dev.to article: https://dev.to/rildev/modern-es6-class-48pb
Link to live proof-of-concept: https://replit.com/#RilDev/ModernES6Class

Is it possible to name a function using arguments passed from another function?

I'm a complete newbie to Javascript so I don't know what its capable of. Any help would be much appreciated!
As the title suggests, I'm trying to pass an argument from a function to name another function inside of it. The method below doesn't work for obvious reasons but I think it conveys what I'm trying to do. The function names need to be very specific for the project I'm working on.
function mainFunc(param1) {
function param1() {}
}
Thanks!
Edit: The software that we are going to start using to go paperless at my work uses a javascript scripting engine. In order for me to do simple things such as:
If at least one of the checkboxes in section A is checked, then you must check at least one checkbox in section B.
I would have to write a function for each and every checkbox field on the form due to the way the software works, the function name has to be specific to the name we assign to the checkbox through their GUI. I was hoping to write a function that writes another function with the specific name, and calls the said function.
function mainFunc(funcName) {
function 'funcName'() {
//do stuff;
}
'funcName'()
}
mainFunc('Checkbox1')
Maybe this will help clarify a little more on what I'm trying to do. Sorry for not being clear the first time around.
You have many options to solve your problem
one option is to return an object with the functions named using the parameters passed to mainFun look at the example below
function mainFunc(param1,param2) {
return {
[param1]:function () {
console.log(" I am function from " + param1)
},
[param2] : function () {
console.log("I am function from " + param2) ;
}
}
}
let hello = 'hello' ;
let greet = 'anything' ;
let functions = mainFunc(hello,greet);
functions['hello']();
functions['anything']();
functions[hello]();
functions[greet]();
if you have many parameters to the mainFun you can also solve it using the arguments object like the example below
function mainFun(par1) {
let myObj = {};
for(let i = 0 ; i<arguments.length;i++){
console.log(arguments[i]);
myObj[arguments[i]] = ()=> {
console.log('You call me from ' + arguments[i]);
}
}
return myObj ;
}
let functions = mainFun('a','b','c','d');
functions['a']();
functions['b']();
functions['c']();
functions['d']();

add photo protototype method not defined js

hi everyone im new to oop in javascript and im trying to make an object model that allows me to store strings that represent a Photo. the Album object should allow you to add a new photo, list all photos, and access a specific photo by the order it was added. but im getting an error that photos.addphoto is not defined. Can someone please
function photo(location,filename){
this.location=location;
this.filename=filename;
}
function album(){
this.photos=[]
}
photo.prototype.addphoto=function(photo){
this.photos.push(photo)
}
photo.prototype.listphoto=function()
{
return this.photos
}
photo.prototype.getphoto=function(){
return this.photo[index-1]
}
var eurtope= new photo("new york","new york.jpg")
var russiae= new photo("england","england.jpg")
var photos=new album()
photos.addphoto(russiae)
photos.addphoto(eurtope)
photos.listphoto(album)
console.log(listphoto(
))
There were a couple of issues, but the main one was that you were adding functions to the photo.prototype whereas you probably meant to add the functions to the album.prototype.
function photo(location,filename){
this.location=location;
this.filename=filename;
}
function album(){
this.photos=[];
}
album.prototype.addphoto=function(photo){
this.photos.push(photo);
}
album.prototype.listphoto=function(){
return this.photos;
}
album.prototype.getphoto=function(index){
return this.photos[index];
}
var eurtope = new photo("new york","new york.jpg");
var russiae = new photo("england","england.jpg");
var photos = new album();
photos.addphoto(russiae);
photos.addphoto(eurtope);
photos.listphoto(album);
console.log(photos.listphoto());
console.log(photos.getphoto(0));
console.log(photos.getphoto(1));

Call a function in node.js programming

I have the following code:
Manager.prototype.checkOrder = function() {
var finish = function(err, filled) {
if(!filled) {
log.info(this.action, 'order was not (fully) filled, cancelling and creating new order');
this.exchange.cancelOrder(this.order);
}
log.info(this.action, 'was successfull');
}
this.exchange.checkOrder(this.order, _.bind(finish, this));
}
And I don't know how to call it on other parts of the code.
I have tried this :
setTimeout(this.checkOrder, util.minToMs(1));
but it didn't work.
I want to do it without using setTimeout function.
As you are using prototypes you probably want to create an Object first. After that you can call the method like every other function.
var myManager = new Manager();
myManager.checkOrder();

React invalid date

var Timeframe = React.createClass({
getInitialState: function() {
return {
tfs: getParameterByName('tfs'),
tfe: getParameterByName('tfe')
}
},
formatTime: function(time) {
var full = new Date(time);
console.log(time);
console.log(full);
return (full).toString('dddd, MMMM ,yyyy');
},
render: function () {
return (
<div>Timeframe: {this.formatTime(this.state.tfs)} - {this.formatTime(this.state.tfs)}</div>
);
}
});
I have an outside js function called getParameterByName which, in these cases, is going to return a time in unix time. As far as I know, Date() works very well with these numbers, and in my experience outside of React, I've never had any trouble with this. When I try using Date within my react function, it's returning invalid date. Does anybody know why this might be happening?
Try this: full.toString('dddd, MMMM ,yyyy');
Instead of: (full).toString('dddd, MMMM ,yyyy');
If you need to work with date, a good choice is to use Moment library.

Categories