No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Recursos

Aportes 12

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Les comparto mis apuntes. 😄

Set

Es parecido a un get, solo que este no retorna nada, es un método void, pero no hace falta colocarle lo que retorna, ya que va a dar error.

A set lo podemos usar para tener reglas de modificación para nuestros parámetros.

Sintaxis

class ClassName {
		constructor () {
				statements
		}

		set methodName () {
				statements
		}
}

There are some principles to improve yor code and make it cleaner. One thing you can do better is to avoid the use of Else, so a simple solution for a code that requires an else is to validate first the scenario that throw the error and then assign the value, in the example of Nicolas it would stay like this:

  set month(newValue: number) {
    if(newValue < 1 || newValue > 12 ){
      throw new Error ("The month needs to be a number between 1 and 12")
    }
    this._month = newValue;
  }

el get y set dan interacción como si fueran una propiedad

Getters and setters

export type formatDate = 'days' | 'months' | 'years';

class MyDate {
    private _year: number;
    private _month: number;
    private _day: number;
    private _leapYear: boolean = false; // by deafault the year is not leap year

    private _months: { [key: number]: string; } = { // dictionari months of the year
        1: 'January',
        2: 'February',
        3: 'March',
        4: 'April',
        5: 'May',
        6: 'June',
        7: 'July',
        8: 'August',
        9: 'September',
        10: 'October',
        11: 'November',
        12: 'December'
    };

    private _month31: number[] = [1, 3, 5, 7, 8, 10, 12]; // list of months that have 31 days

    constructor(year: number, month: number, day: number) {
        this._year = this._validYear(year);
        this._validLeapYear()
        this._month = this._validMonth(month);
        this._day = this._validDay(day);
    }

    printFormat(format: string = 'dd / nm / yy'): string {
        if (this._validError() == null) { // if validError returns null then there are no errors
            let day: string = this._addPadding(this._day);
            let month: string = this._addPadding(this._month);
            format = format.replace('yy', this._year.toString());
            format = format.replace('dd', day);
            format = format.replace('mm', month);
            format = format.replace('nm', this._months[this._month]);
            return format;
        } else {
            return this._validError()!; // notation ! tells typescript that the programmer is in control
        }
    }

    // override
    toString(): string {
        return this.printFormat();
    }

    get day(): number {
        return this._day;
    }

    set day(num: number) {
        this._day = this._validDay(num);
    }

    get month(): number {
        return this._month;
    }

    set month(num: number) {
        this._month = this._validMonth(num);
        this._day = this._validDay(this._day); // this line verifies the assigned values setters
    }

    get monthName(): string {
        return this._months[this._month];
    }

    get year(): number {
        return this._year;
    }

    set year(num: number) {
        this._year = this._validYear(num);
    }

    get leapYear(): boolean {
        return this._leapYear;
    }

    private _validError(): string | null {
        // if any attribute has the value of zero then it is out of range and there is an error
        let error: string = '#outRange!'; // out of tange error indicator

        if (this._year == 0) {
            return `${error} year`; // error message
        }
        if (this._month == 0) {
            return `${error} month`; // error message
        }
        if (this._day == 0) {
            return `${error} day`; // error message
        }
        return null; // whithout errors
    }

    private _addPadding(num: number): string {
        if (num < 10) {
            return `0${num}`;
        }
        return num.toString();
    }

    private _validYear(year: number): number {
        // if the year is greater than zero it is valid
        if(year > 0) {
            return year;
        } else {
            return 0;
        }
    }

    private _validDay(day: number): number {
        // validate the day
        if (day > 0) {
            if (this._month === 2) { // if the month is february
                let evaluateDay: number = 28;
                if (this._leapYear) { // if leap year
                    evaluateDay++;
                }
                if (day <= evaluateDay) {
                    return day;
                } else {
                    return 0;
                }
            } else { // if it is any month except february
                let evaluateDay: number = 30;
                if (this._month31.includes(this._month)) { // if the month has 31 days
                    evaluateDay++;
                }
                if (day <= evaluateDay) {
                    return day;
                } else {
                    return 0;
                }
            }
        } else {
            return 0
        }
    }

    private _validMonth(month: number): number {
        // Validated that the month is between 1 and 12
        if (month > 0 && month < 13) {
            return month;
        } else {
            return 0;
        }
    }

    private _validLeapYear(): void {
        /**
         * @ Check if the year is a leap year
         */
        let result: number;
        result = (this._year / 4) % 2; // formula if ((n/4) % 2 == 0)

        if(result == 0) {
            this._leapYear = true;
        }
    }

    add(amount: number, format: formatDate): void {
        if (this._validError() == null) {
            if (format == 'days') {
                for (let i = 0; i < amount; i++) {
                    this._day += 1;
                    if (this._validDay(this._day) == 0) { // Validated the day based on the month and year
                        /* if _validDay returns 0 the valid days for the current month
                        were exceeded then the month is increased and day is restarted */
                        this._month++;
                        if (this._month == 13) {
                            this._year++;
                            this._month = 1;
                        }
                        this._day = 1;
                    }
                }
            } else if (format == 'months') {
                for (let i = 0; i < amount; i++) {
                    this._month++;
                    if (this._month > 12) {
                        this._year++;
                        this._month = 1;
                    }
                }
            } else if (format == 'years') {
                if (amount > 0) {
                    this._year += amount;
                }
            }
        }
    }
}

const myDate = new MyDate(2000, 2, 29);
console.log(myDate.printFormat('dd of nm of yy'));
myDate.add(3, 'days');
console.log(myDate.printFormat());
myDate.add(40, 'months');
console.log(myDate.printFormat('mm-dd-yy'));
console.log(myDate.toString());
console.log(myDate.day);
console.log(myDate.month);
console.log(myDate.monthName);
console.log(myDate.year);

myDate.day = 31;
myDate.year = 2000;
myDate.month = 2;
console.log(myDate.day);
console.log(myDate.toString());

Les comparto mi código implementando tratamiento de errores.

export class MyDate {

  constructor(
    public year: number = 1984,
    public _month: number = 6,
    private _day: number = 26) {}

  printFormat(): string {
    const day = this.addPadding(this._day);
    const month = this.addPadding(this._month);
    return `${this.year}/${month}/${day}`;
  }

  private addPadding(value: number) {
    if (value < 10) {
      return `0${value}`;
    }
    return `${value}`;
  }

  public add(amount: number, type: 'days' | 'months' | 'years') {
    if (type === 'days') {
      this._day += amount;
    }
    if (type === 'months') {
      this._month += amount;
    }
    if (type === 'years') {
      this.year += amount;
    }
  }

  get day() {
    return this._day;
  }

  get isLeapYear(){
    if(this.year % 400 === 0) return true
    if(this.year % 100 === 0) return false
    return this.year % 4 === 0
  }

  get month(){
    return this._month
  }

  set month(value: number){
    try{
      if(value >= 1 && value <= 12){
        this._month = value
      }
      else{
        throw new Error('month out of range')
      }
    }
    catch(e){
      const error = (e as Error).message;
      console.log(error)
    }
  }
}

const newDate = new MyDate(2004, 3, 9);
console.log(newDate.month)


const newDate2 = new MyDate(2004, 3, 9);
newDate2.month = 11
console.log('(11)=>',newDate2.month)


const newDate3 = new MyDate(2004, 3, 9);
newDate3.month = 25
console.log('(error',newDate3.month)

console.log('With error handling')

rango de meses no era entre 0 y 11??, entonces porque usaste entre 1 y 12?

Excelente video ahora me queda claro los setters y los getters

Ya que estamos en TS, podríamos también crear un tipo para month, de manera que solo puedan asigarse valores predefinidos en el tipo ¿no?

El tipo de retorno del get debe ser asignable con el tipo de entrada para el set, es decir:

get month(): number {}
set month(value: number) {}

No podría tener un get de la siguiente forma:

get month(): string {
    return this.addPadding(this._month)
}

Algo que me parece interesante es que los setters no se ejecutan como una funcion sino como una igualdad directamente

Estas reglas también funcionan para los métodos internos, como el add 🤯🤯🤯.

  public add(amount: number, type: 'days' | 'months' | 'years') {
    if (type === 'days') {
      this.day += amount;
    }
    if (type === 'months') {
      this.month += amount;
    }
    if (type === 'years') {
      this.year += amount;
    }
  }

Setters

Los setters DEBEN ser void.

set month(newMonth: number) {
  if (newMonth < 1 || newMonth > 12) {
    throw new Error('Invalid month');
  }
  this._month = newMonth;
}

const anotherDate = new MyDate(2024, 1, 1);
anotherDate.month = 5;
//anotherDate.month = 50; //! Error