묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Provider 자동완성
FutureProvider만 쳐도 아래와 같이 자동 완성이 되어야 하는데,final FamilyModifierProvider = FutureProvider((ref) => 0);와 같이 자동 완성이 되어야 하는데,final FamilyModifierProvider = FutureProvider(_createFn)이렇게만 자동 완성 됩니다....ref.listen(provider, (previous, next) {});ref.read(listenProvider.notifier).update((state) => null);이것도 자동 완성이 안돼서 직접 코드 치면서 따라하고 있는데 너무 불편해서요.Vscode 윈도우 사용 중이고, 확장에서 Flutter 삭제하고 재설치해도 안되네요... pubspec.yaml에도 패키지 잘 넣어준 것 같은데... 다른 분 컴퓨터에서는 자동 완성 잘 됩니다. 혹시 원인 및 해결 방법 아시는 분이 계시다면 답변 부탁드리겠습니다!
-
해결됨[입문] Qt QML과 C++로 시작하는 크로스플랫폼 앱 개발
VisualStudio 2022 로 사용해도 큰 문제는 없나요?
VisualStudio 2022 로 사용해도 큰 문제는 없나요?2019 버전 다운로드가 막혔네요.Dev essential 가입해도 커뮤니티 버전은 막혔고 Visual C++ Redistributable for Visual Studio 2019 은 다운이 되는것 같은데, 2022 버전 사용해도 문제 없으면 2022버전 사용하려고 합니다. 어떤가요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
throttle해도 API가 2번 불릴때..
throttle을 적용해서 fetchmore동작이 제 기대치는 화면 하단부분 가면 한번 불리고 다시 리스트 랜더링되고 다시 화면 하단부분 가야 fetchmore API가 불려야하는데 화면 하단 부분 가면 fetchmore가 2번 불리네요물론 같은 api요청은 아니고 lastId가 다르게 2번 불리는데 fetchmor불리면 controller의 maxScrollExtent이 바뀌어서 한번만 불려야하는데 왜 2번불릴까요;
-
해결됨[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
go_router 로그인 성공후 홈화면 이동
로그인 성공해서 userModelLoading에서 userModel로 잘 바뀌었는데 홈화면으로 이동이 안되네요껏다가 다시키면 값은 잘 세팅 되어서 redirect쪽에서 홈화면은 잘가는걸 확인했는데 어디를 의심해야할지 몰라서 질문드립니당
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
메모리에 있지 않은 데이터 캐시처리 이후
메모리에 있지 않은 데이터의 캐시처리는 어떻게 하는지 가르쳐주셨는데 만약 음식탭에서 레스토랑에 없는 음식을 선택해서 state 를 추가하게 되면레스토랑 페이지에서 추가 데이터를 가져오게 되면 paginate(after: 새롭게 추가된 id) 가 되서 새롭게 추가된 id이후로 fetchCount를 가져올테니중간에 건너뛰는 일이 중간에 누락될 거 같은데 선생님은 어떻게 생각하세요??
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
paginate 일반화 하기 전에도요 ~
paginate를 일반환하는 과정에서 meta가 중요한 곳은 따로 처리를 안하고 data를 쓰는 부분에서 <T>를 추가해서 다음과 같이 final pState=State as CursorPagination<T>;라고 사용하셨는데 사실 일반화 전에도 Restaurant만paginate할떄도 final pState=State as CursorPagination<RestaurantModel>;을 안쓰셨는데 , 일반화 때문이 아니라도 dynamic 타입이 들어가니까 원래 써야 하는 곳이 아닌가 해서요 이때는 왜 안썼는지 궁금합니다. 강의 항상 잘보고 있습니다 감사합니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
riverpod2.0으로 common의PaginationProvider만들기
@Riverpod( keepAlive: true, ) class PaginationNofifier<T extends IModelWithId, U extends IBasePaginationRepository<T>> extends _$PaginationNofifier { final U repository; PaginationNofifier({ required this.repository, }); @override CursorPaginationBase build() { final state = CursorPaginationLoading(); paginate(); return state; }codegenertator를 이용해서 PaginationProvider만들고 있는데 초기값은 build에서 설정은 했는데 repository를 생성자로 해서 받을려고 하는데 아래처럼 생성자 정의를 해도 에러가 나네요. The class PaginationNofifier must have a default constructor.다른 곳에서 비슷한 사례를 찾아봐도 기본 인스턴스 프로퍼티 자체를 받는 에제가 없어서 질문드립니다
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Body로 인한 서버 리소스 관련
항상 강의 잘 보고있습니다!NestJS 강의를 보고 다시 중급 강의를 보다보니, 서버 관련된 부분을 더 이해하기 쉬웠습니다만, 이 섹션에서 PatchBasket을 요청할 때 body값에 object가 아닌 List로 요청을 보내기 때문에 추가하고싶은 상품정보 뿐만 아니라, 기존에 장바구니에 담겨있던 모든 상품들까지 같이 Patch요청이 되게 설계를 해 놓으셨더라구요. 현업에서도 보통 이런 방식을 사용하는건가요? 아니면 큰 의도 없이 설계하신건가요?다른종류의 상품이 수십개가 존재할 경우, 리소스 낭비가 되지 않을까 해서 여쭤봅니다!
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
상태 설계 관련 질문드립니다.
안녕하세요 코드팩토리님좋은 강의 제공해주셔서 너무 많이 배워갑니다.앱 설계 중에 궁금한 점이 생겨서 코드팩토리님의 의견을 들어보고자 질문 남깁니다. 하나의 화면에서 여러 개의 프로바이더를 참조하고 있는 경우 모든 프로바이더의 상태가 제대로 fetch 되어야만 화면을 보여주고, 하나라도 상태가 없다면 에러 화면을 보여주는 기능을 만들고 싶습니다.이 경우에 화면 단위로 화면과 관련된 상태 (isLoading, isError)를 관리해주는 provider를 만들어주기도 하나요? (ex. HomeScreenProvider)만약 이렇게 화면과 관련된 상태를 관리해주는 provider를 만들어준다고 하면 그 provider(HomeScreenProvider) 에서 다른 provider(feature1Provider, feature2Provider ...)를 의존하게 될텐데provider 끼리 서로 의존하게 되는게 좋은 설계인지도 궁금합니다. (provider 끼리는 같은 layer라고 생각이 들어서 입니다) 감사합니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Restaurant Pagination 요청해보기 - 이미지 404 문제
Image provider: NetworkImage("http://10.0.2.2:3000/img/파스타/까르보나라.jpg", scale: 1.0)Image key: NetworkImage("http://10.0.2.2:3000/img/파스타/까르보나라.jpg", scale: 1.0)안녕하세요.페이지네이션 요청 중 음식 사진이 자꾸 404 에러가 발생합니다.http://127.0.0.1:3000/img/떡볶이/떡볶이.jpg위 링크 또는 제 아이피를 넣어봤지만 모두 404에러가 발생하네요.사진 제외 음식 이름부터 별점까지는 모두 적용된 상태입니다.올려주신 서버 레포지토리상의 이미지들은 모두 정상인데혹시 이유를 알 수 있을까요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
TabController ScrollController 초기화 타이밍
TabController은 late 키워드를 써서 나중에 initState에서 초기화하는데 ScrollController은 디폴트값 넣어서 이미 만들더라고여 TabController은 왜 그렇게 하는지 알수있을까요지금 후반쪽 보고 있어서 강의중에 이미 말씀하셧다면 죄송합니다late TabController controller; @override void initState() { super.initState(); controller = TabController(length: 4, vsync: this); controller.addListener(tabListener); }final controller = ScrollController();
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
인터셉터 질문입니다
1)인터센터 구현하실 때 storage를 주입해서 사용했고final FlutterSecureStorage storage;다른 스플래쉬 스크린에서는 const로 common > const > data.dartfinal storage = FlutterSecureStorage(); 에 있는 storage를 가져다 쓰고 있습니다.stateless, stateful widget도 결국 class가 청사진 이라고 생각되는데모두 storage;를 주입 받아야 하지 않나요? 궁금합니다..! 2)인터셉터에서 선생님께서 onRequest 에 return super.onRequest(options, handler); 부분이 핸들러가 에러를 발생시킬지 , 정상처럼 진행시킬지 알아서 결정한다고 하셔서 그럼 혹시 여기서도 return handler.reject와 return handler.resolve를 쓸 수 있나요?? 3) 인터셉터에서 onError에 if(/auth/token 경로도 아니고 && 401일때){ ...}그외에는 return handler.reject(err)를 사용했는데 사실 그대로 에러를 내는 거면 return super.onError(err,handler); 를 써도 되지 않나요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
PaginationProvider의 로직 중 이해안가는 부분이 있습니다.
RestaurantPagination-5 2:25경에 나오는 부분입니다.if (fetchMore) { final pState = state as CursorPagination<T>; state = CursorPaginationFetchingMore( meta: pState.meta, data: pState.data, ); paginationParams = paginationParams.copyWith( after: pState.data.last.id, ); } // 데이터를 처음부터 가져오는 상황. else { // 만약에 데이터가 있는 상황이라면 // 기존 데이터를 보존한 채로 Fetch를 진행한다. // 여기!! if (state is CursorPagination && !forceRefetch) { final pState = state as CursorPagination<T>; state = CursorPaginationRefetching<T>( meta: pState.meta, data: pState.data, ); } else { state = CursorPaginationLoading(); } }해당로직에서 "// 여기!!"로 표시한 부분에서if(state is CursorPagination && !forceRefetch)조건문이 이해가지 않습니다.fetchMore는 아닌데 새로고침(forceRefetch)도 아니다. 그런데 데이터를 이미 가지고 있고 새로운 데이터를 요청한다?이게 어떤 경우를 의미하고 작성된 케이스일까요?
-
미해결Only Javascript만으로 배우는 하이브리드앱 패키징
onesignal 연동 시 black screen
window.plugins.OneSignal.setAppId(); 위 코드 입력 시 화면이 black screen으로 표시됩니다. 하지만 onesignal 연동도 잘되고 푸시 메시지 발송되 잘 됩니다. 원인이 무엇일까요? android 구버전과 최신버전 모두에서 그렇습니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
retrofit multipartfile 리스트 보내기
@POST('/boards') @Headers({'Authorization': 'true'}) @MultiPart() Future<HttpResponse> createBoard({ @Part() required BoardRequestModel boardCreateModel, @Part() List<MultipartFile>? files, });이렇게 multipartfile 리스트로 이미지를 보내려고 하는데생성된 g.dart 파일을 보면 이렇게 에러가 발생합니다현재 getx 에서 Multipartfile을 hide 해주고 사용했습니다혹시 retrofit을 이용할때 multipartfile 리스트를 보내는 방법이 따로 있을까요?
-
해결됨[입문] Qt QML과 C++로 시작하는 크로스플랫폼 앱 개발
visual studio 2019 버전 다운로드가 안보여요.
강의 "개발환경 셋팅" 보고 있는데요.MSVC 2019 설치 링크에 들어가 봤는데, 저는 visual studio 2019 다운로드 버튼이 안보이네요. 다운로드 받을 수 있는 방법이 있을까요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Rating의 get 요청이 가질 않습니다.
안녕하세요. 강의를 들으며 ratingState를 print 해보니 Instance of '_RestaurantRatingRepository' 결과가 나왔습니다. 이제보니 dio 요청 자체도 가지 않은 상태입니다. pagination_provider.dart를 적용한 후 Restaurant와 RestaurantDetail은 잘 실행되는데, Rating만 dio 요청 자체가 가지 않습니다.저 아래의 Instance of '_RestaurantRatingRepository'가 ratingState입니다.디버깅을 통해서 dio를 제대로 받아온 것은 확인했는데, pagination 내부의 print는 restaurant만 먹히고, restaurantdetail과 rating은 print되지 않아 어떻게 해결해야할지, 어떻게 해결 방법을 찾아야 할지 갈피도 못 잡겠습니다.프로젝트의 repository를 첨부합니다. https://github.com/jungeyo3/codefactory-flutter-lv2-study 버전은 아래와 같습니다. 감사합니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
redirect와 refresh 질문드려요
안녕하세요 선생님 ^^강의 듣고 있는중에 궁금한 것이 생겼습니다 1)gorouter 7버전에서듣고(4버전 건너뛰고) -> 프로젝트에 적용하기 단원보고 있는데요 갑자기 refresh라는 개념이 나와서요 7버전에서는 없었는데 .... refresh라는 기능 없이도 충분히 만들수 있나요?아니면 7버전에서 refresh비슷한 기능이 있나요?? 2)redirect를 통해 이동한 페이지는 Appbar에서 뒤로가기가 없던데 이것이 redirect 특징인 건가요? 3)redirect를 사용해서 뒤로가기버튼이 없는 상태에, 만약에 context.pop을 하게 된다면 어디로 이동하게 되나요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
에러가 생겨서 질문드립니다
에러 내용W/WindowOnBackDispatcher(25534): OnBackInvokedCallback is not enabled for the application.W/WindowOnBackDispatcher(25534): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest. 증상:실행시키면 녹색바탕에 codefactory 로고 와 인디케이터 화면이 나오면서 무지 오래 20분 이상 계속 되다가 로그인 화면으로 들어가네요로그인 화면으로 바로 들어가야 하는데요. 그게 안되고 있습니다.로그인 화면으로 들어갈 때 첨부한 사진 하단 2줄 메세지가 나오네요 (에러 내용 참조) 검색하면 증상 대처법이 나오는데 따라해도 똑같습니다.설정 어디를 바꾸면 될거도 같은데 찾지 못하고 있습니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
BottomNavigationBar 질문
검색 방법이 잘못된건지 모르지만 구글에 검색해도 해결법이 나오지않아 질문 올립니다. bottomNavagtionBar: GestureDetector( onTap: (){ Navigator.push(context, MaterialPageRoute(builder: (context) => CommentRegisterScreen( id: widget.id))); }, child: TRoundedContainer( height: 60, backgroundColor: const Color(0xffF8F8FA), padding: const EdgeInsets.all(TSizes.defalutSpace), radius: 0, child: Text( '댓글을 남겨보세요.', style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.grey), ), ), ), child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(TSizes.defalutSpace), child: Column( children: [ const SizedBox(height: TSizes.spaceBtwItems), SizedBox( height: MediaQuery.of(context).size.height, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: PaginationListViewV2( model: state, id: widget.id, provider: commentProvider(widget.id), itemBuilder: <Comment>(_,index,comment){ if(index == 0){ return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// 제목 Text(state.title, style: Theme.of(context).textTheme.headlineMedium), const SizedBox(height: TSizes.spaceBtwItems), /// 닉네임 Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ const TRoundedImage( width: 24, height: 24, fit: BoxFit.fill, imageUrl: 'asset/img/no_image.png', borderRadius: 100, ), const SizedBox(width: TSizes.sm), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( state.creator, style: Theme.of(context).textTheme.bodyLarge, ), ], ), ], ), const SizedBox(height: TSizes.spaceBtwItems), /// 날짜, 좋아요 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( state.createDate.split("T")[0], style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.grey), ), GestureDetector( onTap: button.disable==false ? () async { //버튼 비활성화 await button.change(); await check == -1 ? ref.read(communityProvider.notifier).clickFavorite(widget.id) : ref.read(communityProvider.notifier).downFavorite(widget.id); await ref.read(favoriteProvider.notifier).updateFavorites(widget.id); //버튼 활성화 await button.change(); } : null, child: check == -1 ? TRoundedContainer( showBorder: true, padding: const EdgeInsets.all(TSizes.sm), borderColor: Colors.redAccent, radius: 10, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( '좋아요', style: Theme.of(context).textTheme.labelMedium!.copyWith(color: Colors.redAccent), ), const SizedBox(width: TSizes.xs), Text( state.favorite.toString(), style: Theme.of(context).textTheme.labelMedium!.copyWith(color: Colors.redAccent), ), ], ), ) : TRoundedContainer( padding: const EdgeInsets.all(TSizes.sm), backgroundColor: Colors.redAccent, radius: 10, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ child: SizedBox( height: 120, child: ListView.separated( shrinkWrap: true, scrollDirection: Axis.horizontal, itemCount: imgs.length, separatorBuilder: (_, __) { return const SizedBox(width: TSizes.spaceBtwItems / 2); }, itemBuilder: (_, int index) { return TRoundedImage( imageUrl: imgs[index].toString().trim(), width: 120, height: 120, fit: BoxFit.fill, borderRadius: 12.0, isNetworkImage: true, ); }, ), ), ), ], ) : const SizedBox(), const SizedBox(height: TSizes.spaceBtwSections), /// 글 내용 Text( state.content.trim(), style: Theme.of(context).textTheme.bodyMedium!.copyWith(height: 1.5), ), /// 댓글 0이 아닐 경우 Row( children: [ Text('댓글', style: Theme.of(context).textTheme.bodySmall), const SizedBox(width: TSizes.spaceBtwItems / 2), Text(state.commentCnt.toString(), style: Theme.of(context).textTheme.bodySmall), ], ), const SizedBox(height: TSizes.spaceBtwItems), CommentCard( comment:comment, recomments:comment.commentList, board_id: widget.id ) ], ); } return CommentCard( comment:comment, recomments:comment.commentList, board_id: widget.id ); }), ), Container( height: 210 ) ] ), ), // Center(child: Text('첫 댓글을 남겨주세요.', style: Theme.of(context).textTheme.bodySmall)), ], ), ), ),위 코드와 같이 BottomNavigationBar와 SinglechildScrollView를 같이 사용하고 있습니다. 가장 하단의Container( height: 210 )위 코드를 넣어주지 않을 시 화면 스크롤이 모두 안되고 짤리는 현상이 발생합니다. 혹시 이러한 경험이 있어 해결방법이 있다면 알려주시면 감사하겠습니다.