일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 시즌드라마
- miniproject
- 견뎌야하나요
- 신생아수면홈캠
- 댕냥이 cctv
- 고화질홈캠
- VanillaJS
- 실손보험
- 문제해결가이드
- fontend
- 초격자캠프
- 중첩배열
- removeButton
- 홈캠앱
- 함수를 반복적으로 호출하려면
- Array.filter
- 오즈코딩스쿨
- 홈캠 야간모드
- 실시간 모니터링
- TroubleShooting Guide
- JavaScript
- 수료후기
- 가성비홈캠
- 홈캠 360
- 빌트인함수
- 개발부트캠프
- preventDefault()
- web
- Challenge
- JSON.stingify
- Today
- Total
Nomard Life
miniProject - 사용자정보 관리 본문
2024.04.16.화
자바스크립트 12일차 ( 총 17일차 )
과제 정보
주제 : 객체리터럴과 localstorage를 이용하여 사용자 정보 저장하기
기본 요구사항
- 객체 리터럴을 이용해 사용자 정보를 정의해야합니다.
- JSON.stringify() 메서드를 이용해 객체를 JSON 형식의 문자열로 변환해야합니다.
- JSON.parse() 메서드를 이용해 JSON 형식의 문자열을 객체로 변환해야합니다.
- localstorage.getItem() 메서드를 이용해 사용자 정보를 불러와야합니다.
- localstorage.setItem() 메서드를 이용해 사용자 정보를 저장해야합니다.
- 개발자 도구 Application/Local Storage 에서 저장한 사용자 정보를 확인해야합니다.
html
<h1>사용자 정보 관리</h1>
<label for="nameInput">이름:</label>
<input type="text" id="nameInput" /><br /><br />
<label for="emailInput">이메일:</label>
<input type="email" id="emailInput" /><br /><br />
<button onclick="saveUserInfo()">저장</button>
<div id="userInfo"></div>
javascript
function saveUserInfo() {
const name = document.getElementById('nameInput').value;
const email = document.getElementById('emailInput').value;
// 'name'과'email'을 키로 사용하는 객체 리터럴 userInfo를 생성
// 로컬스토리지에 사용자의 정보를 저장
document.getElementById(
'userInfo'
).innerText = `이름: ${name}, 이메일: ${email}`;
}
// 로컬 스토리지에서 사용자 정보 불러오는 코드
// 페이지 로드 시 저장된 사용자 정보가 있으면 화면에 표시
if (savedUserInfo.name && savedUserInfo.email) {
document.getElementById(
'userInfo'
).innerText = `이름: ${savedUserInfo.name}, 이메일: ${savedUserInfo.email}`;
}
’name'과'email'을 키로 사용하는 객체 리터럴 userInfo를 생성
const userInfo = {
name: name,
email: email,
};
로컬스토리지에 사용자의 정보를 저장
localStorage.setItem('user', JSON.stringify(userInfo));
로컬 스토리지에서 사용자 정보 불러오는 코드
const savedUserInfo = JSON.parse(localStorage.getItem('user'));
입력하고 나니script.js:35 Uncaught TypeError: Cannot set properties of null (setting 'innerText')
에러가 발생했다.
if (savedUserInfo.name && savedUserInfo.email) {
document.getElementById(
'userInfo'
).innerText = `이름: ${savedUserInfo.name}, 이메일: ${savedUserInfo.email}`;
}
이 부분에서 에러가 발생한 것인데, innerText 는 위의 saveUserInfo에서는 잘 작동되던 메소드였다…
stackoveflow에서 검색해보니 렌더링이 되기 전에 요소를 참조하지 못해서 null참조 오류가 나오는 거라고..
해결 방안 첫번째는 순서를 변경하는것. 이미 최 하단에 있기때문에 결과에 변동이 있을것같지 않다.
두번째 방법은 이벤트 후킹. 아래는 본 프로젝트와 관련없는 단순 예시이다.
window.onload = function() {
what();
function what(){
document.getElementById('hello').innerHTML = 'hi';
};
}
위의 예시를 참고하여 수정해보았다.
window.onload = function () {
if (savedUserInfo.name && savedUserInfo.email) {
console.log(savedUserInfo);
document.getElementById(
'userInfo'
).innerText = `이름: ${savedUserInfo.name}, 이메일: ${savedUserInfo.email}`;
}
};
추가로 동기분들이 해결한 방법중에 하나는 html문서
head
에 있는 script를body
로 옮겨서 해결하셨다고 한다. (본문에는 body만 있고 head는 없지만 head 영역에 script 링크가 걸려있었다)
스크립트 링크를 옮기지 않고 해결할 수 있는 다른 방안으로는 아래의 코드로 수정하면 된다.
document.addEventListener('DOMContentLoaded', () => {
if (savedUserInfo.name && savedUserInfo.email) {
document.getElementById(
'userInfo'
).innerText = `이름: ${savedUserInfo.name}, 이메일: ${savedUserInfo.email}`;
}
});
여기서 DOMContentLoaded
는 브라우저가 HTML을 전부 읽고 DOM 트리를 완성하는 즉시 발생한다. dㅣ미지 파일이나 스타일시트 등의 기타 자월은 기다리지 않는다.window.onload
는 스타일, 이미지 등의 리소스들이 모두 로드되었을 때 실행된다.
사용에 맞게 골라 쓰면 될 것 같다
DOMContentLoaded 와 window.onload 차이 || javascript.info
최종 완성 된 .js 파일
// 사용자 정보 저장 함수
function saveUserInfo() {
const name = document.getElementById('nameInput').value;
const email = document.getElementById('emailInput').value;
const userInfo = {
name: name,
email: email,
};
localStorage.setItem('user', JSON.stringify(userInfo));
document.getElementById(
'userInfo'
).innerText = `이름: ${name}, 이메일: ${email}`;
}
const savedUserInfo = JSON.parse(localStorage.getItem('user'));
// 페이지 로드 시 저장된 사용자 정보가 있으면 화면에 표시
window.onload = function () {
if (savedUserInfo.name && savedUserInfo.email) {
console.log(savedUserInfo);
document.getElementById(
'userInfo'
).innerText = `이름: ${savedUserInfo.name}, 이메일: ${savedUserInfo.email}`;
}
};
개인 PC라면 상관없지만 공용PC라면 개발자 도구 Application/Local Storage 에서 저장한 사용자 정보를 별도로 삭제해야 한다. (프로젝트 상 삭제하거나 초기화 하는 기능은 개발하지 않았다)
코드 및 미리보기는 다음에서 확인 해 볼 수 있다.
두번째 과제 - 사용자정보 입력 2
주제 : map() 메서드와 filter()메서드를 사용해 사용자 정보를 관리할 수 있다.
기본 요구 사항
- 주어진 ‘users’ 배열에서 나이가 25 이상 35 미만인 사용자를 필터링하여 새로운 배열을 생성해야합니다.
- 필터링된 사용자 중에서 이메일 주소가 ‘
gmail.com’ 도메인을 사용하는 사용자만을 추출하여 새로운 배열을 생성해야합니다. - ‘renderUserData’함수 내부에서는 각 사용자의 정보를 HTML 요소로 구성하여 화면에 표시합니다.
⠀html 문서
<div id="userData"></div>
<script src="./script.js"></script>
javascript
const users = [
{ name: 'John', age: 30, email: 'john@example.com' },
{ name: 'Alice', age: 25, email: 'alice@gmail.com' },
{ name: 'Bob', age: 35, email: 'bob@gmail.com' },
{ name: 'Emma', age: 28, email: 'emma@example.com' },
{ name: 'Steve', age: 32, email: 'steve@gmail.com' },
];
// 25세 이상 35세 미만인 사용자만을 필터링하여 새로운 배열 생성
// 필터링된 사용자 중에서 이메일 주소가 gmail.com 도메인을 사용하는 사용자만을 추출하여 새로운 배열 생성
// 결과를 화면에 그리는 함수
function renderUserData(userData) {
const userDataDiv = document.getElementById('userData');
// innerHTML을 사용해 결과를 화면에 그려보세요
}
renderUserData(gmailUsers); // 사용자 데이터를 그리는 함수 실행
25세 이상 35세 미만인 사용자만을 필터링하여 새로운 배열 생성
function range(age) {
return age < 35 && 24 < age;
}
const result = users.filter(range(users.age));
첫 시도는 실행되지 않았다.
Uncaught TypeError: boolean false is not a function at Array.filter (
배열에는 아무것도 담지 못함.. 에러문 확인해보니 함수지만(?) 함수가 아니라나….ㅠfilter
내 함수에서 인자를 받는게 아닌 ture / false 값만 인식 해야하므로 range 함수 자체에서 모든걸 해결해야 했다.
두번째 도전은 성공
function range(users) {
if (users.age < 35 && users.age > 24) {
return true;
} else {
return false;
}
}
const result = users.filter(range);
console.log(result)
를 찍어보면 age
가 35세인 Bob
을 제외한 4명이 생성된 배열에 잘 배치되어 있었다.
궁금해서 다른 방법이 있는지 조금 더 찾아보니 아래와 같은 코드도 있었다.
stackoverslow에서 찾은 코드는 다음과 같다.
let its = (prop) => (x) => x[prop];
let inRange = (rng) => (x) => rng.min < x && x < rng.max;
Function.prototype.is = function (p) {
return (x) => p(this(x));
};
const range = { min: 24, max: 35 };
const result = users.filter(its('age').is(inRange(range)));
console.log(result);
아직 배우지 않은 람다식인가? 변수를 정의하는 모습이 매우 간결해 보이고 가독성이 좋다.
하지만 아직 이해할 수 있는 문법이 아니기에.. 기록으로만 남겨두려 한다.
참조 문서는 여기에서 볼 수 있다.
필터링된 사용자 중에서 이메일 주소가 gmail.com 도메인을 사용하는 사용자만을 추출하여 새로운 배열 생성
// 메일 주소 도메인이 gmail.com 인 사용자
function gmailUser(ageUsers) {
const mail = ageUsers.email;
const domain = mail.slice(-9);
if (domain === 'gmail.com') {
return true;
} else {
return false;
}
}
const gmailUsers = ageUsers.filter(gmailUser);
javascript 문자열에서 gmail.com
으로 끝나는 단어만 자르기 위해 str.slice()
를 사용하였다. 뒤에서부터 자르기 위해 -9
를 인수로 사용하였다.
결과를 화면에 그리는 함수
function renderUserData(userData) {
const userDataDiv = document.getElementById('userData');
console.log(userData);
userData.map(() => {
userDataDiv.innerHTML = `
<span> 이름 : ${userData.name}</span>
<span> 나이 : ${userData.age}</span>
<span> 메일 : ${userData.email}</span>
`;
});
}
첫 시도 실패.. 화면에 그려지기는 하나 ${userData.name}
값이 undefined
으로 출력된다.console.log(userData)
로는 배열이 잘 찍히는 것으로 보아 리터럴에서 접근을 잘못 입력한 듯하다.
이것 저것 시도해보니 화살표 함수에 (user)
값을 받아서 리터럴에서도 user.name
을 전달하니 잘 출력되는것을 확인했다.
그리고, 한명만 출력되어서 map을 innetHTML 안으로 배치했더니 2명이 모두 잘 출력되는 것을 볼 수 있었다.
최종 .js 파일
const users = [
{ name: 'John', age: 30, email: 'john@example.com' },
{ name: 'Alice', age: 25, email: 'alice@gmail.com' },
{ name: 'Bob', age: 35, email: 'bob@gmail.com' },
{ name: 'Emma', age: 28, email: 'emma@example.com' },
{ name: 'Steve', age: 32, email: 'steve@gmail.com' },
];
// filter : 25 세 이상 35세 미만
function range(users) {
if (25 <= users.age && users.age < 35) {
return true;
} else {
return false;
}
}
const ageUsers = users.filter(range);
// 메일 주소 도메인이 gmail.com 인 사용자
function gmailUser(ageUsers) {
const mail = ageUsers.email;
const domain = mail.slice(-9);
if (domain === 'gmail.com') {
return true;
} else {
return false;
}
}
const gmailUsers = ageUsers.filter(gmailUser);
// 결과를 화면에 그리는 함수
function renderUserData(userData) {
const userDataDiv = document.getElementById('userData');
userDataDiv.innerHTML = userData.map(
(user) =>
`
<div class="user">
<p><strong> 이름 : </strong> ${user.name}</p>
<p><strong> 나이 : </strong> ${user.age}</p>
<p><strong> 메일 : </strong> ${user.email}</p>
</div>
`
);
}
// 사용자 데이터를 그리는 함수 실행
renderUserData(gmailUsers);
원래 공부하는 스타일은 일단 시작하면서 막히는 부분이 있으면 잠깐 찾아보다가 적용하고 완료하고나면
작업한 내용중 인상 깊었던 것을 정리하는 식으로 했었는데, 작업 시간이 길어지다 보면 기억이 잘 안 날때도 있고 아예 생각이 안나는 경우도 많았다.
그래서 작업할 때 아예 에디터를 켜놓고 바로바로 적어서 정리해 가면서 하니 내가 어느부분에서 막혔는지, 어떤방법을 써서 오류를 잡았는지가 잘 보여서 더 좋은 것 같다. 다만 시간이 조금 더 걸린다는 것..
좀 더 익숙해지고 검색이 덜 필요할 쯤에는 조금 더 나아지지 않을까..
1차 미션과제는 오전중으로 금방 끝났는데 2차 미션과제에서 시간이 지체된 것 같다.
거의 두세배는 더 걸린것 같다… ㅠ
'Develop' 카테고리의 다른 글
나의 첫 스터디 (2) | 2024.04.19 |
---|---|
VSCode - 문법오류(?)시 뿌꾸뿌꾸 소리 없애기 (1) | 2024.04.17 |
TroubleShooting Guide - 문제해결가이드 (0) | 2024.04.16 |
miniProject - 로또 번호 추첨 & 로또 번호 자동 생성 기능 구현 (0) | 2024.04.15 |
miniProject - 햄버거 주문서 (0) | 2024.04.12 |