No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Aplicaci贸n de fromEvent en PlatziWordle

9/36
Recursos

Aportes 16

Preguntas 2

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

MI SOLUCI脫N
Consiste en a帽adir un nuevo observador para el caso espec铆fico de borrar una letra, lo llam茅 deleteLetter y suscribirse al observable onKeyDown$.
No es una buena implementaci贸n a帽adir un elseIf al observador insertLetter porque como su nombre lo dice, 煤nicamente es para insertar letras.

Ac谩 mi c贸digo:

/**
 * Aplicaci贸n de fromEvent en PlatziWordle:
 * fromEvent nos ayuda a atrapar eventos generados por elementos en el DOM.
 */

import { fromEvent } from "rxjs";

const letterRows = document.getElementsByClassName("letter-row");
const onKeyDown$ = fromEvent(document, "keydown");
let letterIndex = 0;
let letterRowIndex = 0;

const insertLetter = {
    next: (event) => {
        const pressedKey = event.key.toUpperCase();
        if (pressedKey.length === 1 && pressedKey.match(/[a-z]/i)) {
            let letterBox =
                Array.from(letterRows)[letterRowIndex].children[letterIndex];
            letterBox.textContent = pressedKey;
            letterBox.classList.add("filled-letter");
            letterIndex++;
        }
    },
};

const deleteLetter = {
    next: (event) => {
        const pressedKey = event.key.toUpperCase();
        if (pressedKey === 'BACKSPACE') {
            let letterBox =
                Array.from(letterRows)[letterRowIndex].children[letterIndex-1];
            letterBox.textContent = null;
            letterBox.classList.remove("filled-letter");
            letterIndex--;
        }
    },
};

onKeyDown$.subscribe(insertLetter);
onKeyDown$.subscribe(deleteLetter);

Me adelant茅 un poco e implement茅 que se pueda agregar las letras en la siguiente row. Adem谩s, us茅 Typescript.

import "../src/styles/main.css"
import { fromEvent } from "rxjs";

const onKey$ = fromEvent<KeyboardEvent>(document, "keydown"); //Se crea el observable que lanza un
//evento cuando se presione una tecla.

const wordleRows: Element[] = Array.from(document.querySelectorAll(".wordle__row"));


const regex: RegExp = /[a-z]/i;

class Wordle {

	constructor(
		private maxIndex: number,
		private maxRow: number,
		private index: number = 0,
		private rowIndex: number = 0,
	){
		this.maxIndex--;
		this.maxRow--;
	}

	private alterWordle = (addingLetter: boolean): void => {
		if (addingLetter) {
			if (this.maxIndex > this.index) {
				this.alterIndex(true);
			} else {
				this.alterIndex(true, true);
				this.alterRowIndex(true);
			}
		} else {
			if (this.index === 0 && this.rowIndex !== 0) {
				this.alterIndex(false, false);
				this.alterRowIndex(false);
			} else if(this.index !== 0){
				this.alterIndex(false);
			}
		}
	}

	public writeLetter = (letter: string): void => {

		wordleRows[this.rowIndex].children[this.index].textContent = letter.toUpperCase();
		this.alterWordle(true);
	};

	public deleteLetter = () => {
		this.alterWordle(false);
		wordleRows[this.rowIndex].children[this.index].textContent = " ";
	};

	private alterIndex = (isIncreasing: boolean, atBeginning?: boolean): void => {
		if (atBeginning === undefined) {
			if(isIncreasing) {
				this.index++;
			} else {
				this.index--;
			}
		} else {
			if (isIncreasing && atBeginning){
				this.index = 0;
			} else if (!isIncreasing && !atBeginning){
				this.index = this.maxIndex;
			}
		}

	}

	private alterRowIndex = (isIncreasing: boolean): void => {
		if(isIncreasing && this.rowIndex < this.maxRow) {
			this.rowIndex++;
		} else if (isIncreasing && this.rowIndex !== 0){
			this.rowIndex--;
		}
	}

}

const wordle = new Wordle(5, 6);

const observatorLetter = { //Se crea el observador que indica como usar谩 la data obtenida.
	next: (event: KeyboardEvent) => {
		const keyPressed = event.key;

		if (keyPressed.match(regex) && keyPressed.length === 1) {
			wordle.writeLetter(keyPressed);
		}
	},
	complete: () => {
		console.log("There is no more events");
	},
	error: (error: Error) => {
		console.log("Something went wrong: ", error.message);
	}
}

const observatorBackSpace = { //Se crea el observador que indica como usar谩 la data obtenida.
	next: (event: KeyboardEvent) => {
		const keyPressed = event.key;

		if (keyPressed === "Backspace") {
			wordle.deleteLetter();
		}
	},
	complete: () => {
		console.log("There is no more events");
	},
	error: (error: Error) => {
		console.log("Something went wrong: ", error.message);
	}
}

onKey$.subscribe(observatorLetter); //Se subscribe el observador al observable.
onKey$.subscribe(observatorBackSpace);

Hola a todos !
Esta es una posible solucion al exercicio =)
Espero tengan un buen dia!

else if(pressedKey === "BACKSPACE"){
        letterIndex--;
        let letterBox =
        Array.from(letterRows)[letterRowIndex].children[letterIndex];
        
        letterBox.textContent = ""
        letterBox.classList.remove("filled-letter")
    }

馃槉 Ahora que conocemos c贸mo funciona fromEvent vamos a implementarlo en PlatziWordle.

Este profe pens贸 en todo, que orden, que buenas explicaciones, que mimo que le da al curso, seguro era estudiante de platzi

Una alternativa para validar que solo se ingresen letras, es a trav茅s del atributo 鈥渒eyCode鈥 del evento 鈥渒eyDown鈥 Ej:

import { fromEvent } from "rxjs";

const onKeyDown$ = fromEvent(document, "keydown");

const insertLetter = {
  next: (event) => {
    const pressedKeyCode = event.keyCode;
    const pressedKey = event.key;

    //Only allow alpha characters
    if (pressedKeyCode >= 65 && pressedKeyCode <= 90) {
      console.log(pressedKey);
    }
  },
};

onKeyDown$.subscribe(insertLetter);

Aporte platzi wordle

Hola a tod@s.
Aqu铆 mi aportaci贸n. He llevado la implementaci贸n a una clase que crea una instancia de cada row y encapsula todo su comportamiento. De esta forma, en cada nuevo intento crearemos una nueva instancia pas谩ndole el elemento .letter_row correspondiente. En el futuro, si a帽adimos un teclado virtual o m谩s posibles comportamientos, quiz谩s ser铆a interesante valorar a帽adir un patr贸n command para gestionar los diferentes comandos (escribir, borrar, confirmar, pegar, clickar una tecla en el teclado virtual, etc). Aqu铆 va el c贸digo:

import {fromEvent, Observable} from "rxjs";

class LetterRow {
  private index: number = 0;
  private onKeyDown$: Observable<Event> = fromEvent(document, 'keydown');

  private constructor(public readonly element: Element) {
    this.onKeyDown$.subscribe({
      next: (event: any) => {
        switch(event.key) {
          case 'Backspace':
            this.delete();
            break;
          default:
            this.type(event.key);
        }
      }
    });
  }

  static create(element: Element) {
    LetterRow.validate(element);
    return new LetterRow(element);
  }

  static validate(element: Element): void {
    if (!element) {
      throw new Error('No valid element');
    }
  }

  private type(key: string): void {
    if (this.isEndOfRow()) return;
    const pressedKey: string = key.toUpperCase();
    if (pressedKey.length === 1 && pressedKey.match(/[A-Z]/)) {
      let letterBox: Element = this.element.children[this.index];
      letterBox.textContent = pressedKey;
      letterBox.classList.add('filled-letter');
      this.moveForward();
    }
  }

  private delete(): void {
    let letterBox: Element = this.element.children[this.index - 1];
    letterBox.textContent = '';
    letterBox.classList.remove('filled-letter');
    this.moveBackward();
  }

  private moveForward(): void {
    if (this.isEndOfRow()) return;
    this.index++;
  }

  private moveBackward(): void {
    if (this.index <= 0) return;
    this.index--;
  }

  private isEndOfRow(): boolean {
    return this.index >= this.element.children.length;
  }
}

const letterRows: HTMLCollection = document.getElementsByClassName('letter-row');
let letterRowIndex = 0;
const row: LetterRow = LetterRow.create(Array.from(letterRows)[letterRowIndex]);

Regex:

pressedKey.match(/[a-z]/i)

Mi soluci贸n

import { fromEvent } from "rxjs";
const letterRows = Array.from(document.getElementsByClassName('letter-row') || [])
const onKeyDown$ = fromEvent(document, 'keydown');
let letterIndex = 0;
let letterRowIndex = 0;

const insertLetter$ = {
  next: (value) => {
    const pressedKey = value.key;
    if (letterRowIndex > 5) {
      return
    }
    if (pressedKey.length == 1 && pressedKey.match(/[a-z]/i) && letterIndex <= 4) {
      let letterBox = letterRows[letterRowIndex].children[letterIndex];
      letterBox.textContent = pressedKey.toUpperCase();
      letterBox.classList.add('filled-letter');
      letterIndex++;
    }

    if (pressedKey == 'Backspace' && letterRows[letterRowIndex].children[letterIndex - 1]) {
      let letterBox = letterRows[letterRowIndex].children[letterIndex - 1];
      letterBox.textContent = null;
      letterBox.classList.remove('filled-letter');
      letterIndex--;
    }

  },
  complete: () => {
    console.info('Finished');
  },
  error: (error) => {
    console.error(error)
  }
}
onKeyDown$.subscribe(insertLetter$);
import { fromEvent } from "rxjs";

const letterRows = document.getElementsByClassName("letter-row");
const onKeyDown$ = fromEvent(document, "keydown");

const onKeyDownErase$ = fromEvent(document, "keydown");

let letterRowIndex = 0;
let letterIndex = 0;
let arrLetters = [];

const insertLetter = {
  next: (event) => {
    const pressedKey = event.key.toUpperCase();
    if (
      pressedKey.length === 1 &&
      pressedKey.match(/[a-z]/i) &&
      arrLetters.length < 5
    ) {
      arrLetters.push(pressedKey);
      let letterBox = Array.from(letterRows)[letterRowIndex].children[letterIndex];
      letterBox.textContent = pressedKey;
      letterBox.classList.add("filled-letter");
      letterIndex++;
    }
  },
};

const eraseLetter = {
  next: (event) => {
    const pressedKey = event.key;
    if (pressedKey === "Backspace" && arrLetters.length !== 0) {
      arrLetters.splice(letterIndex - 1, 1);
      let letterBox = Array.from(letterRows)[letterRowIndex].children[letterIndex - 1];
      letterBox.textContent = "";
      letterBox.classList.remove("filled-letter");
      letterIndex--;
    }
  },
};

onKeyDown$.subscribe(insertLetter);
onKeyDownErase$.subscribe(eraseLetter);
 if ( pressedKey == 'Backspace'.toUpperCase()) {debugger
            letterBox = Array.from(letterRows)[letterRowIndex].children[letterIndex - 1];
            letterBox.textContent = '';
            letterBox.classList.remove("filled-letter");
            letterIndex--;
        }

Muy buen reto, me hizo pensar al principio, pero ya resuelto, las pistas ayudan mucho.

Me encanta la did谩ctica de este maestro,
Mi soluci贸n al reto es un nuevo observador:

const eraseLetter = {
  next: (event) => {
    if ( event.keyCode === 8) {
      let letterBox = Array.from(letterRows)[letterRowIndex].children[letterIndex - 1];
      letterBox.textContent = '';
      letterIndex--;
    }
  }
}

onBackDelete$.subscribe(eraseLetter);

Mi soluci贸n es la siguiente.

Utilice el mismo observable para detectar cuando se precione el boton para borrar y valide que si el index es 0 no pase nada.

import { fromEvent } from 'rxjs';

const letterRows = document.getElementsByClassName('letter-row');
const onkeyDown$ = fromEvent(document, 'keydown');
let letterIndex = 0;
let letterRowIndex = 0;

const insertLetter = {
    next: (event) => {
        
        const pressedKey = event.key;
        if(pressedKey === 'Backspace') {
            if( letterIndex <= 0) return;

            letterIndex --;
            let letterBox = Array.from(letterRows)[letterRowIndex].children[letterIndex];
            letterBox.textContent = '';
            letterBox.classList.remove('filled-letter');
        }

        if(letterIndex === 5) return console.log('salto de linea.');

        if(pressedKey.length === 1 && pressedKey.match(/[a-z]/i)) {

            let letterBox = Array.from(letterRows)[letterRowIndex].children[letterIndex];
            letterBox.textContent = pressedKey
            letterBox.classList.add('filled-letter');
            letterIndex ++;
        } 

    }
};

onkeyDown$.subscribe(insertLetter);

No es necesario crear otro observador para este reto, sin embargo para el curso est谩 bien. Mi soluci贸n en un poco minimalista jejeje.
Solo pregunto por c贸digo ASCII de la tecla retroceso (8) y luego lo envi贸 a una funci贸n que haga el trabajo. As铆 evito un doble subscribe.

let letterIndex = 0;
let letterRowIndex = 0;
const insertLetter = {
  next: (event) => {
    const pressedKey = event.key.toUpperCase();
    const BACK = event.keyCode === 8 ?? event.key;
    if (BACK) {
      letterIndex--;
      return backLetter(letterRows);
    }
    if (pressedKey.length === 1 && pressedKey.match(/[a-z]/i)) {
      let letterBox = letterRows[letterRowIndex].children[letterIndex];
      letterBox.textContent = pressedKey;
      letterBox.classList.add("filled-letter");
      letterIndex++;
    }
  },
};

function backLetter(letterRows) {
  let letterBox = letterRows[letterRowIndex].children[letterIndex];
  letterBox.textContent = "";
  letterBox.classList.remove("filled-letter");
}
onKeyDown$.subscribe(insertLetter);

Comparto mi solucion al ejercicio

<code> 
onKeyDownObservable$.subscribe( {
    next: (value) => {
        console.log(value);
        if (value.code === 'Delete' || value.code == 'Backspace') {
            deleteLetter();
        } else if  ( value.key?.length == 1 && value.key?.match(/[a-z]/i) ){
            //solo debe aceptar letras
            setLetter( value.key );
        } else {
            console.log("solo letras");
        }
    }
});

function deleteLetter(){
    letterCol = letterCol == 0 ? 0 : letterCol-1;    
    const acualLetter = Array.from(letterRows)[letterRow].children[letterCol];
    acualLetter.textContent = null;
    acualLetter.classList.remove('filled-letter')
}