이야기를 나눠요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
[리뉴얼] React로 NodeBird SNS 만들기
안녕하세요, 질문입니다..!
안녕하세요 제로초님 제로초님의 노드버드 강의에 날씨 기능을 추가해서 작업을 해보고있습니다... 현재 제로초님의 강좌를 챕터 5 노드 연결 초반까지 진행해놓고 날씨 api 를 받아와서 뿌리고싶어서 작업중에 있습니다. 그런데 에러의 원인을 알 수가 없어서요..ㅜㅜ 제가 사가나 리듀서쪽에서 뭘 잘못한건지.. 일단 코드를 보여드리겠습니다.. (컴포넌트, 리듀서, 사가 순 입니다) import React, { useEffect, useMemo } from 'react'; import { Card, Spin, Space } from 'antd'; import styled from 'styled-components'; import { useDispatch, useSelector } from 'react-redux'; import { CALL_WEATHER_REQUEST } from '../reducers/weather'; const Weather = () => { const dispatch = useDispatch(); const { weatherInfo, location, weatherCallLoading } = useSelector( state => state.weather ); // 스타일 컴포넌트를 준 부분은 불필요할거같아 뺏습니다 ㅎㅎ const cardStyle = useMemo(() => ({ marginTop: 10 }), []); useEffect(() => { dispatch({ type: CALL_WEATHER_REQUEST }); }, []); console.log(`나야....${weatherInfo.name}`); return ( <div> <Card title='오늘의 날씨' style={cardStyle}> <WeatherStyle> {weatherCallLoading === false ? ( <div> <WeatherIcon> {/* <img src={`/images/${weatherInfo.weather[0].main}.png`} role='presentation' /> */} </WeatherIcon> <div> <p> <span>{weatherInfo.name}</span> {/* {weatherInfo.weather[0].description} */} </p> <p>{/* 현재 온도 <span>{weatherInfo.main.temp}°C</span> */}</p> </div> </div> ) : ( <Space size='middle'> <Spin size='large' /> </Space> )} </WeatherStyle> </Card> </div> ); }; export default Weather; 우선 날씨를 보여주는 컴포넌트 부분입니다. 주석을 준 부분이 에러를 일으키는 부분입니다. ㅠㅠ 그냥 weatherInfo.name 같이 object type 이 아닌 객체인 경우 에러를 일으키지않지만 weatherInfo.weather[0].description 같은 값은 이런 에러가 발생합니다. 우선 리듀서와 사가의 코드부터 이어서 보여드리고 에러에 대해 자세히 말씀드리겠습니다. import produce from 'immer'; export const initialState = { weatherCallLoading: false, weatherCallDone: false, weatherCallError: null, weatherInfo: [], location: {} }; export const CALL_WEATHER_REQUEST = 'CALL_WEATHER_REQUEST'; export const CALL_WEATHER_SUCCESS = 'CALL_WEATHER_SUCCESS'; export const CALL_WEATHER_FAILURE = 'CALL_WEATHER_FAILURE'; export const callWeatherRequestAction = data => { return { type: CALL_WEATHER_REQUEST, data }; }; const dummyWeather = data => ({ ...data // city: data.location, // temperature: '-5', // weatherState: '비', // icon: 'rain', // comment: '눈사람 되겠어요.' }); const reducer = (state = initialState, action) => { return produce(state, draft => { switch (action.type) { case CALL_WEATHER_REQUEST: draft.weatherCallLoading = true; draft.weatherCallDone = false; draft.weatherIcon = null; break; case CALL_WEATHER_SUCCESS: draft.weatherCallLoading = false; draft.weatherCallDone = true; draft.weatherInfo = dummyWeather(action.data); draft.weatherIcon = null; break; case CALL_WEATHER_FAILURE: draft.weatherCallLoading = false; draft.weatherCallError = action.error; break; default: break; } }); }; export default reducer; 리듀서 부분입니다. import axios from 'axios'; import { all, call, fork, put, takeEvery, takeLatest } from 'redux-saga/effects'; import { CALL_WEATHER_FAILURE, CALL_WEATHER_REQUEST, CALL_WEATHER_SUCCESS } from '../reducers/weather'; function weatherAPI() { // component 에서 지역선택값 받아오기 // const city = action; // ** weatherkey 값 부분은 보이면 안될거같아 가렸습니닷... return axios.get( `https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=${weatherKey}&lang=kr&units=metric` ); } function* weather(action) { // const today = datetime.datetime.today(); try { const result = yield call(weatherAPI); yield put({ type: CALL_WEATHER_SUCCESS, data: result.data }); console.log(result.data); } catch (err) { yield put({ type: CALL_WEATHER_FAILURE, error: err.response.data }); } } function* watchWeather() { yield takeLatest(CALL_WEATHER_REQUEST, weather); // yield takeEvery(CALL_WEATHER_REQUEST, weather); } export default function* weatherSaga() { yield all([fork(watchWeather)]); } 이렇게 까지 코드입니다. 에러는 앞서 말씀드린대로 object 가 아닌 데이터를 가져오면 잘 나오는데, object 객체를 불러오면 다음과 같은 에러가 뜹니다... 다음과 같은 에러가 뜨면서 500에러와 함께 오픈 api 요청을 무지하게 하드라구요ㅠㅠ 굳이 object 가 아니여도 weatherInfo.main.temp 같은 객체도 에러가 뜨는거보면 두번 거쳐서 불러오는 게 문제인가 싶기도합니다ㅠ 그리고 신기한게 문제가 되는 코드를 주석처리하고 서버를 렌딩한 다음에 새로고침을 하지않고 주석을 풀고 저장을 하면 에러가 뜨지않고 아래 그림처럼 정상으로 화면에 보여집니다. 다음과 같이 잘 나와요...그런데 새로고침을 하면 500에러가 뜹니다... 새로고침을 하면 500에러가 뜨는거라 api 를 불러올 때 느려서 undefined 에서 찾으려고해서 500에러가 뜨는거라고 생각이 드는데요... (weatherInfo 값을 콘솔을 찍어보니 처음 렌딩할때 undefined 가 두번 찍히더라구요, 그 다음 제대로 불러오고요) 그런데..api 불러올때 처음에 undefined 라서 그런거라면...왜 weatherInfo.name 값은 정상적으로 불러오면서... 그것보다 깊게 들어간 배열이나 객체값은 500 에러가 뜨는건지..ㅠ 잘 모르겠습니다... 제가 api를 잘 못 불러오고있는건지..ㅜㅜㅜ 머리가 터질거같아요... 아, 그리고 api 는 이렇게 되어있습니다 제 깃헙 주소는 이거입니다ㅠㅠ https://github.com/haerim95/anonymous-caster
-
대세는 쿠버네티스 (초급~중급편)
Pod말고 Node도 리플리카셋처럼 구성할 수 있나요?
안녕하세요. 약간 바보같은 질문일 수도 있는데요... 쿠버네티스 사용 시 ReplicaSet, Deployment를 통해 Pod를 관리해서 Pod 개수를 늘리거나 줄이지 않습니까? 그런데 어차피 node는 한정적인데 왜 Pod 갯수를 최대로 맞춰서 셋업을 하지 않고 Replicaset을 사용하나요...? 그리고 AWS AutoScaling 처럼 Node 자체를 늘려주는 기능은 없는 건가요? 몇 번 다시 봐서 어느정도 K8s 용어라든지 사용 방법은 감이 오는데... 원론적인 생각이 들어서요. 감사합니다!
-
[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
번외 질문 드립니다 !!
삭제된 글입니다
-
자바스크립트 비기너: 튼튼한 기본 만들기
드디어 함수네요... 이놈을 꼭 정복하겠습니다...
(사진)
-
코딩으로 학습하는 GoF의 디자인 패턴
C#에서는 파일 관리?를 어떻게 해야 할까요
안녕하세요, 현재 백기선 선생님의 강좌를 결제하여 너무 잘 보고 있는 학생입니다. 저는 현재 C#을 배우고 있기 때문에 C#으로 강의를 진행 중입니다만 강의를 보면 볼 수록 C#에서는 파일을 어떻게 분리해야 할 지 고민이 되어 이렇게 글을 적습니다. (현재 저는 한 cs 파일 안에 모든 클래스와 인터페이스를 넣어서 하고 있습니다.) 자바 인텔리제이에서는 클래스든 인터페이스든 모두 하나 파일 단위로 쪼개서 패키지라는 폴더에 관리하는 것처럼 보였는데 C#에서는 패키지 대신 네임스페이스가 있고, 그런데 폴더라는 것도 있고... 많이 헷갈립니다. 현재 어댑터 패턴을 실습 중인데 해당 패턴에서 나오는 것들만 public interface UserDetails { ... } public interface UserDetailsService { ... } public class Account { ... } public class AccountService { ... } public class AccountUserDetails : UserDetails { ... } public class AccountUserDetailsService : UserDetailsService { ... } public class App { ... } 이렇게 나오는데 각자 하나의 cs 파일로 분리하자니 뭔가 파일 수가 너무 많아지는 거 같고 target 인터페이스 따로, 클라이언트 코드 따로, 어댑터 어댑티 따로 나누자니 뭔가 모르겠고... 혹시 어떤 기준 같은 게 있을까요?
-
코딩으로 학습하는 GoF의 디자인 패턴
잡담이긴한데...
선생님께서 쓰시는 키보드가 궁금하네요.. 메멘토 패턴에서 단축키 얘기를 하니까 키보드 소리가 너무 좋아서 사고 싶네요...
-
코딩으로 학습하는 리팩토링
디자인 패턴에 이어 ...
두 번째 선생님의 강의 입니다. 늘 좋은 퀄리티라서 믿고 듣습니다. ㅎㅎ
-
실전! Querydsl
ToString 관련 질문 드립니다.
안녕하세요 항상 좋은 강의 감사합니다 ^^ team을 제외시키기 위해서 명시적으로 저렇게 작성을 하는데 필드가 추가되는는 경우 tostring도 같이 넣어야 돼서 누락되는 경우가 있어 보이는데 실무에서도 저렇게 직접 명시적으로 사용하는지 궁금합니다!
-
모든 개발자를 위한 HTTP 웹 기본 지식
좋은 강의 너무감사합니다.
영한님 안녕하세요. 웹 백엔드 개발자가 되기 위해 공부중인 학생입니다. 주변 선배님들의 권유로 HTTP강의를 수강하게 되었습니다. 정작 다른 기술스택에 눈이 멀어 기초적인 지식을 게을리한 제 자신에 대해 반성하게 되는 시간이었습니다. 동시에 지금까지 다른 언어나 프레임워크의 기능만을 사용했던 저의 이해가 얼마나 얕았던 지도 깨닫게 되었습니다. 좋은 강의를 준비해주셔서 감사합니다!
-
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
혹시나 최근에 강의 듣는 분들을 위한 BootStrap 버전 Tip
2022.02.07 기준 최신 부트스트랩은 5.1 버전으로 나옵니다. 최신 버전으로 하면 다소 이질감이 느껴지고 회원 가입 폼이 강사님과 매우 다르게 나옵니다. 해결 방법 * BootStrap 4.6 버전으로 낮추기 1. 위 링크로 들어가, CSS, JS -> Bundle 항목의 npm 링크들을 사용. 2. 1의 방법대로 링크를 사용하면 기존의 CSS, JS 다운 파일은 사용하지 않아도 되고, 강사님께서 별도 제작한 jumbotron-narrow.css 만 쓰시면 됩니다. 1.의 링크에 있는 코드 첨부 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
-
휘뚜루마뚜루
슉수수수수슉
-
아무것도 모르고 시작하는 C#
DirectoryInfo 안될 때 방법
using System.IO; 추가해야 DirectoryInfo 사용 할 수 있음
-
파이썬(Python) 기초부터 실무까지 part.2
강사님 정말 인간적이시네요
편집이라도 하시지ㅠㅠㅋㅋㅋ
-
파이썬(Python) 기초부터 실무까지 part.2
23:50에서, 41번 line에 scores[:] -> scores_index[:] 여야합니다.
수정하지 않으면 48번 라인 결과에 영향을 주네요. 단순히 복사한 리스트와 원본 리스트의 요소가 다른 것을 확인하기 위한 시간이었지만 혹시나 궁금해하시는 분들이 있을 것 같아 남깁니다.
-
대세는 쿠버네티스 (초급~중급편)
와 정말 잘봤습니다
이번 강의 특히나 명강의네요... 진짜 한판 정리 대박입니다!!
-
스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ExceptionHandler 우선순위
ExceptionResolver의 우선순위가 왜 ExceptionHandlerExceptionReosolver, ResponseStatusExceptionResolver, DefaultHandlerExceptionResolver의 순서로 되어잇는지 코드를 확인해봤습니다. ExceptionResolver의 우선 순위를 확인할 수 있는 코드는 아래와 같습니다. WebMvcConfigurationSupport 클래스에 addDefaultHandlerExceptionResolvers 메소드는 아래처럼 정의되어 있습니다. protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers, ContentNegotiationManager mvcContentNegotiationManager) { ExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver(); exceptionHandlerResolver.setContentNegotiationManager(mvcContentNegotiationManager); exceptionHandlerResolver.setMessageConverters(getMessageConverters()); exceptionHandlerResolver.setCustomArgumentResolvers(getArgumentResolvers()); exceptionHandlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers()); if (jackson2Present) { exceptionHandlerResolver.setResponseBodyAdvice( Collections.singletonList(new JsonViewResponseBodyAdvice())); } if (this.applicationContext != null) { exceptionHandlerResolver.setApplicationContext(this.applicationContext); } exceptionHandlerResolver.afterPropertiesSet(); exceptionResolvers.add(exceptionHandlerResolver); ResponseStatusExceptionResolver responseStatusResolver = new ResponseStatusExceptionResolver(); responseStatusResolver.setMessageSource(this.applicationContext); exceptionResolvers.add(responseStatusResolver); exceptionResolvers.add(new DefaultHandlerExceptionResolver());} 위의 빨간색으로 표시한 순서대로 List에 add를 하고, 나중에 DispatcherServlet의 processExceptionHandler 메소드에서 List를 순회하기 때문에 이 우선순위대로 동작한다고 이해하시면 좋을 것 같습니다. 당연히 많이들 아시는 내용이고 간단한 내용이라 글 쓰는게 맞나. 부담스러운 부분도 있지만, 저처럼 모르시는 분들을 위해 글써봤습니다.
-
스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
왜 null을 반환하면 계속 진행되고, null 이 아니면 예외를 처리하는지 확인해봤습니다
왜 HandlerExceptionResolver에서 ModelAndView를 null로 하면 에러가 그대로 진행되고, 빈 ModelAndView를 생성하면 예외가 처리되는지 코드를 한번 열어봤습니다. 궁금하실 분도 있을 것 같아서 글 남깁니다. 아래는 DispatcherServlet의 processHandlerException 메소드 입니다. @Nullableprotected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) throws Exception { // Success and error responses may use different content types request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE); // Check registered HandlerExceptionResolvers... ModelAndView exMv = null; if (this.handlerExceptionResolvers != null) { for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) { exMv = resolver.resolveException(request, response, handler, ex); if (exMv != null) { break; } } } if (exMv != null) { if (exMv.isEmpty()) { request.setAttribute(EXCEPTION_ATTRIBUTE, ex); return null; } // We might still need view name translation for a plain error model... if (!exMv.hasView()) { String defaultViewName = getDefaultViewName(request); if (defaultViewName != null) { exMv.setViewName(defaultViewName); } } if (logger.isTraceEnabled()) { logger.trace("Using resolved error view: " + exMv, ex); } else if (logger.isDebugEnabled()) { logger.debug("Using resolved error view: " + exMv); } WebUtils.exposeErrorRequestAttributes(request, ex, getServletName()); return exMv; } throw ex;} 이 전체코드에서 우리가 구현한 resolveException 처리하는 부분만 떼보면 // Check registered HandlerExceptionResolvers...ModelAndView exMv = null;if (this.handlerExceptionResolvers != null) { for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) { exMv = resolver.resolveException(request, response, handler, ex); if (exMv != null) { break; } }} 이렇게 됩니다. 코드를 열어보니 정말 간단하게도 exMv를 null로 초기화해놓고 등록된 resolver들을 돌면서 resolveException을 호출하여 결과가 null 이 아니면 break하는 것을 볼 수 있습니다. 이렇게 만들어진 exMv(모델앤뷰)가 null 이면 (모든 HandlerExceptionResolver 를 다 돌고도 null) 아래의 if문 if (exMv != null) { if (exMv.isEmpty()) { request.setAttribute(EXCEPTION_ATTRIBUTE, ex); return null; } // We might still need view name translation for a plain error model... if (!exMv.hasView()) { String defaultViewName = getDefaultViewName(request); if (defaultViewName != null) { exMv.setViewName(defaultViewName); } } if (logger.isTraceEnabled()) { logger.trace("Using resolved error view: " + exMv, ex); } else if (logger.isDebugEnabled()) { logger.debug("Using resolved error view: " + exMv); } WebUtils.exposeErrorRequestAttributes(request, ex, getServletName()); return exMv;}throw ex; 조건에 걸리지 않아 throw ex;로 에러를 던지게 됩니다. exMv가 null이 아니면 exMv의 여러 상태에서 따라 request에 attribute를 설정하거나, viewName 등록, 로깅 등의 처리를 하는 것을 볼 수 있습니다. 이처럼 코드를 열어보니 설명해주신 내용에 대해 더 이해가 잘 되는 것 같아 이렇게 글로 남겨서 공유합니다!
-
스프링 핵심 원리 - 고급편
영한님 사용하시는 키보드 기종이 어떻게 되시나요?
타건하는 소리가 좋아서 궁금해지네요!
-
갖고노는 MySQL 데이터베이스 by 얄코
잘못된 Tablename을 입력했을때 나오는 Northwind의 설명
안녕하세요! 데이터베이스를 처음 공부하기 시작한 대학생입니다. 이런 저런 실습을 해보다보니 테이블명을 잘못쳤을때, 대소문자를 다르게 쳐보거나하면 Northwind.잘못친테이블명 해서 오류가 나오더라구요. 그런거 누가 몰라 싶을 수도 있는데, Northwind가 뭐지? 싶어서 찾아보니 실습 페이지에 있는 샘플 데이터베이스의 데이터가 마이크로소프트가 제공하는 Northwind 지역의 정보라 데이터베이스 이름인 것 같더라구요. 아무도 질문한 적 없는 것 같아 남겨봅니다. 출처 : https://www.outsystems.com/forge/component-overview/7058/northwind-db 감사합니다.
-
it 취업을 위한 알고리즘 문제풀이 입문 (with C/C++) : 코딩테스트 대비
다르게 한번 풀어봤어요
char a[101], b[101]; int ary[256]; scanf("%s", a); scanf("%s", b); for (int i = 0; a[i] != '\0'; i++) { ary[a[i]]++; } for (int i = 0; b[i] != '\0'; i++) { ary[b[i]]++; } bool flag = false; for (int i = 0; i < 256; i++) { if (ary[i] % 2 != 0) { flag = true; break; } } if (flag) printf("NO"); else printf("YES");