Wordle Maker Project 23일차

PROLCY·2022년 11월 23일
0

Wordle-Maker-Project

목록 보기
23/31
post-custom-banner

오늘은 11월 23일 23일차이다.

목표

  • 오류 해결

진행

드디어 가닥이 잡혔다. 어제 발생했던 오류는 array 메서드를 잘 못 써서 발생한 것이였다. 단어를 입력하면 나는 wordList.splice()를 통해 wordList를 업데이트해줬는데, wordList.splice는 반환값으로 교체한 대상을 담은 배열을 반환하기 때문에 입력한 단어를 제외한 모든 단어를 지워버렸다. 그래서 이 부분을 ... 구문으로 수정했다.

코드

    useEffect(() => { // 렌더링될 때
        connectSocket(params.maker);
        client.get(`/solve/${params.maker}`)
            .then( res => {
                if ( res.data === 'no-session')
                    setMessage('Enter your nickname!');
                else {
                    nickname = res.data.nickname;
                    setLineSet(sixLines);
                    setWordCorrect(res.data.wordCorrect);
                    keyState = res.data.keyState;
                    submitNickname = true;
                    setTimeout(() => { 
                        setWordList(res.data.wordList);
                        setListIndex(res.data.listIndex);
                        console.log("res.wordList", res.data.wordList);
                        setWord(res.data.lastWord);
                        console.log("res.lastWord:", res.data.lastWord);
                        
                    }, 100);
                }
            })
    }, [params]);

우선 solverPage에서 처음 렌더링될 때 실행되는 부분이다. 세션이 여부를 판단하고 없으면 데이터를 받는데, wordList, listIndex, lastWord를 받아 업데이트해준다.

router.get('/:maker', async (req, res) => {
    try {
        console.log(req.session);
        if ( req.session.solver === undefined || !req.session.solver[req.params.maker] ) {
            res.send('no-session');
            return;
        }
        const maker = await Maker.findOne({
            attributes: ['correct_word'],
            where: {
                nickname: req.params.maker,
            },
            include: [{
                model: Solver,
                attributes: ['word_list', 'key_state'],
                where: {
                    nickname: req.session.solver[req.params.maker],
                }
            }],
        });
        let word_list = maker.Solvers[0].word_list;
        let key_state = maker.Solvers[0].key_state;

        word_list = JSON.parse(word_list);
        key_state = JSON.parse(key_state);

        if ( word_list === null )
            word_list = [[]];
        if ( key_state === null )
            key_state = {};

        let last_word, listIndex;

        console.log("word_list", word_list);
        console.log("word_list.length:", word_list.length);
        console.log("element:", word_list[word_list.length - 1]);
        
        if ( word_list[word_list.length - 1].length === 0) {
            listIndex = word_list.length - 1;
            last_word = [];
        }
        else if ( word_list[word_list.length - 1][0].state === 'filled' ) {
            listIndex = word_list.length - 1;
            last_word = word_list[word_list.length - 1];
        }
        else {
            listIndex = word_list.length;
            last_word = [];
        }

        console.log("last_word:", last_word);

        console.log("correct_word:", maker.correct_word, "word_list", word_list);
        res.send({
            wordCorrect: maker.correct_word,
            wordList: word_list,
            keyState: key_state,
            lastWord: last_word,
            nickname: req.session.solver[req.params.maker],
            listIndex: listIndex,
        });
    } catch (error) {
        console.error(error);
    }
});

이 부분은 GET /solve/:maker 요청을 처리하는 라우터이다. db로부터 해당 word_list를 뽑아낸 후, word_list의 상태에 따라 listIndex와 last_word를 결정해준다. word_list의 마지막 요소가 빈 배열이라면, 여기서부터 입력을 시작해야하므로 listIndex는 마지막 인덱스, last_word는 빈 배열로 설정한다. 마지막 요소가 filled 상태라면, 여기서부터 입력을 시작해야하므로 listIndex는 마지막 인덱스, last_word는 마지막 요소로 설장한다. 그외의 경우에는 word_list의 마지막 인덱스까지 다 차있다는 말이므로 listIndex를 마지막 인덱스 다음부터, last_word는 빈 배열로 설정한다.

    useEffect(() => {
        if ( submitNickname  ) {
            console.log('wordlist:', wordList);
            console.log('listIndex:',listIndex);
            if ( wordList[listIndex] === undefined ) {
                setWordList([
                    ...wordList,
                    word
                ]);
            } else {
                setWordList(wordList.map((element, index) => {
                    if ( index === listIndex )
                        return word;
                    else
                        return element;
                }));
            }

            client.post(`/solve/${params.maker}/typing`, { newWord: word, listIndex: listIndex }) // 입력한 단어 및 키 상태 서버에 등록
                .catch(error => {
                    console.log(error);
                })
        }
    }, [word, params]);

이 부분이 핵심인데, word가 바뀔 때마다, 즉 문자를 입력할 때마다 실행되는 부분이다. 만약 해당 인덱스에 요소가 없다면 word를 새로 wordList에 넣어주고, 아니라면 map 함수를 통해 해당 인덱스만 바꿔준다. 이후 서버에 POST /solve/:maker/typing 요청을 보낸다.

router.post('/:maker/typing', async (req, res) => {
    // solver 테이블에 등록
    const solver = await Solver.findOne({
        attributes: ['word_list'],
        where: {
            nickname: req.session.solver[req.params.maker],
            maker: req.params.maker,
        }
    });
    let word_list = JSON.parse(solver.word_list);
    console.log(req.body.newWord, req.body.listIndex);
    if ( word_list === null )
        word_list = [];
    console.log(word_list.length);
    if ( word_list.length === req.body.listIndex )
        word_list.push(req.body.newWord);
    else if ( word_list.length > req.body.listIndex)
        word_list.splice(req.body.listIndex, 1, req.body.newWord);

    word_list = JSON.stringify(word_list);

    await Solver.update({
        word_list: word_list,
    }, {
        where: {
            nickname: req.session.solver[req.params.maker],
            maker: req.params.maker,
        }
    });

    req.app.get('io').of('/loader').to(req.params.maker).emit('enter', await getSolvers(req.params.maker));

    console.log(word_list);
    res.end();
});

POST /solve/:maker/typing 요청을 처리하는 라우터이다. solver 테이블에서 word_list를 뽑아주고, listIndex와 word_list의 상태에 따라 push나 splice를 해준다. 이후 req.app.get('io')~ 로 시작하는 부분은 웹소켓을 통해 solvers 데이터를 전송하는 부분이다.

보충할 것

  • js 객체 메서드들의 반환형 잘 기억하기

내일 할 것

  • 오류 해결(한 번씩 coloring된 단어가 서버에 제대로 전달되지 않음, 요청 문제인듯)
  • 세션 지우기 구현

마무리

드디어 문자 단위 웹소켓이 제대로 작동한다. 5일차동안 시간을 여기에만 썼는데, 이제야 되서 다행이라는 생각이 든다. 동시에 나는 아직도 많이 부족하구나라는 생각도 든다. 더 열심히 해야겠다는 생각이 든다.

post-custom-banner

0개의 댓글