바닐라 JS로 크롬 앱 만들기 12

이지예·2022년 9월 17일
0

JavaScript

목록 보기
24/24

< To Do List >

Loading To Dos

새로고침을 해도 이전의 toDo 들을 복원하는 기능을 추가하고 싶다.
application이 시작될 때 toDos array를 빈 값으로 시작하지 않고, localStorage에 toDo들이 있으면 toDos에 parsedToDos를 넣어서 이전 값을 복원한다.

이때 toDos 배열의 타입을 const에서 let으로 바꿔주는것이 중요하다.
let으로 바꿔주지 않으면 새로고침후 값이 저장되지 않기 때문이다.

//todo.js
let toDos = [];
//...
if (savedToDos) {
    const parsedToDos = JSON.parse(savedToDos);
    toDos = parsedToDos; 
    parsedToDos.forEach(paintToDo);
}

그런데 이 방식은 삭제를 해도 local storage에는 값이 남아있어서 새로고침 하면 삭제한 값들이 남아있다.

Deleting To Dos

local storage는 toDos array를 복사해두는 곳이다. toDos array와 local storage는 같지 않다.
HTML과 JavaScript는 deleteToDo함수를 실행하면 어떤 HTML의 element를 지워야하는지 알고 있지만, 어떤 todo text를 데이터베이스에서 지워야하는지는 모른다. 예를 들어, 같은 글자가 저장 돼 있는 경우 몇번째 데이터를 지워야 하는지 모른다.
todo들을 text대신 object로 만들어서 id같은것을 주면 된다.

//todo.js
function handleToDoSubmit(event){
  //...
  const newTodoObj={
    text:newTodo,
    id:Date.now() //element가 만들어질 때 Date.now()를 이용해서 랜덤하게 ID를 만들어준다.

  }
  toDos.push(newTodoObj);
  paintToDo(newTodoObj); //입력받은 객체를 paint함수로 전달한다.
  saveToDos();
}

handleToDoSubmit 함수에서 text를 push하던 것을 object를 push하도록 바꾼다.

//todo.js
function paintToDo(newTodo){ //원래 text를 입력 받았자만, 지금은 object를 입력받으므로, object안의 text를 사용한다.
  const li = document.createElement("li");
  li.id = newTodo.id; //입력받은 객체의 id를 새로 만든 li태그의 id로 설정한다.
  span.innerText=newTodo.text;
  //...
}

삭제하려는 글자의 id 얻기

filter기능을 사용하면 원하지 않는 부분은 빼고 결과를 얻어낼 수 있다.

//ex
const todos=[{text:"one"},{text:"two"}]
function Filter(todo){return todo.text!=="one"}
todos.filter(Filter) // [{text:"two"}]
//todos.filter(todo =>todo.text!=="one")도 같은 기능이다.

filter 함수를 사용하면 배열의 요소 각각을 filter함수에 넣어준 함수에 적용하여 결과값을 return 받는다. 결과값을 return받지 못한 요소는 빼고 값을 얻어낼 수 있다.

todo list에서 지우고싶은 id가 있는 todo를 지우려고 한다. 그러면 toDos array도 새로고쳐줘야 한다. toDos가 local storage에 저장돼 있기 때문이다.

//todo.js
function deleteToDo(event){
  //...
  toDos=toDos.filter((toDo)=> toDo.id!==parseInt(li.id)); //toDo는 toDos DB에 있는 요소 중 하나다. 이 함수는 DB에 있는 모든 요소가 실행된다. 클릭했던 li의 id를 갖고있는 toDo를 지운다.
  //toDo의 id들은 숫자인데, li.id들은 문자열이기 때문에 둘 다 같은 형으로 바꿔준다.
  saveToDos(); //DB에서 todo를 지운 후에 다시 local storage를 갱신한다.
} 

Geolocation

사용자의 위치를 받아서, 화면에 날씨를 보여주자.

getCurrentPosition

두개의 인자가 필요하다. 에러가 없을 때 실행 될 함수, 에러가 발생했을 때 실행 될 함수이다.

//weather.js
function onGeoOk(position){
  console.log(position);
} 
function onGeoError(){
  alert("Can't find you. No weather for you.");
} 
navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);

getCurrentPosition의 success함수는 GeolocationPosition object 하나를 입력 받는다. 그 안에 coords(좌표)값을 보면 내가 있는 곳의 위도와 경도를 알 수 있다.

//weather.js
function onGeoOk(position){
  const lat = position.coords.latitude;
  const lng = position.coords.longitude;
  console.log("You live in", lat, lng); //위도와 경도를 변수로 받아와서 콘솔창에 출력한다.
}

이 숫자들을 장소로 바꿔주려면 어떻게 해야할까?
우선 API계정을 얻어야 한다. API는 다른 서버와 이야기할 수 있는 방법이다.
openweathermap.org 사이트에서 By geographic coordinates를 사용해서 URL로 위치좌표를 보내서 정보를 받아보자.
내 위도, 경도, api키를 입력하면 내 상세 위치 정보가 나온다.

//weather.js
function onGeoOk(position){
  //...
    const url = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${API_KEY}` //백틱 안에 URL을 써야 한다.
    console.log(url); //위에서 언급한 openweathermap.org사이트에서 받아온 사용자의 위치정보를 알 수 있는 url을 console창에 출력한다.
}

fetch

콘솔창에 URL을 출력하는것 대신 fetch를 사용해서 URL을 얻어보자. fetch(url)을 실행 후 f12->Network에 가면 wifi에서 무슨 일이 일어나는지 보여준다. JavaScript가 fetch를 사용해서 URL로 요청을 한 것을 볼 수 있다.
(만약 전송받은 값 중 온도를 화씨에서 섭씨온도로 바꾸고 싶다면, url의 뒤에 &units=metric을 입력하면 된다.)



fetch로 얻어온 값을 사용하고 싶다.
fetch는 promise이다. promise는 당장 뭔가 일어나지 않고 시간이 걸린 뒤 일어난다. 서버에 요청 했는데 서버가 응답하는 시간이 걸린다고 한다면 그 응답을 기다려야 한다. 그래서 then함수를 사용한다.

//weather.js
function onGeoOk(position){
  //...
  fetch(url).then(response => response.json().then(data=>{
                                                  console.log(data.name, data.weather[0].main)}); //URL을 fetch하고, response를 받아야 한다. 그리고 response의 json을 얻어야 한다. response의 json은 fetch로 URL요청을 받아 얻은 결과 전부를 말한다. 내용을 추출했으면 data를 얻는다.
                  //weather은 array로, data.weather은 array의 첫번째 요소의 main을 얻어야 한다.
                  //출력결과 : Seoul Clouds
}
//weather.js
function onGeoOk(position){
  //...
  fetch(url).then(response => response.json().then(data=>{
                                                  const name = data.name;
    const weather = data.weather[0].main;}); //지역, 날씨 변수 추가
}

html에서 태그를 만들어보자

<!--index.html-->
<!--...-->
<div id = "weather"> <!--id가 weather인 div 태그 생성-->
  <span></span>
  <span></span>
</div>
<!--script들-->

javascript에서 id를 받아오는 변수를 생성한다.

//weather.js
function onGeoOk(position){
  //...
  fetch(url).then((response)=>response.json().then((data)=>{
  //const weatherContainer = document.getElementById("weather");
    const weather = document.querySelector("#weather span:first-child"); //span에 날씨를 줘야하기 때문에 querySelector
    //...id가 weather인 span의 첫번째 child를 얻어야 한다.
    const city = document.querySelector("#weather span:last-child");
        city.innerText = data.name; //원래 name 
    weather.innerText = `${data.weather[0].main} / ${data.main.temp}`; //원래의 const weather, 온도를 받아온다.
    
  //...
  });
}

0개의 댓글