묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
super.repository에 대해 궁금합니다.
class RestaurantRatingStateNotifier extends PaginationProvider<RatingModel, RestaurantRatingRepository> { RestaurantRatingStateNotifier({ required super.repository, });}super는 부모쪽의 것을 받아온다고 알고 있는데제네릭으로 상속받을 클래스에 레포지토리를 명시해서 RestaurantRatingRepository 를 가져올 수 있는걸까요?제네릭에 대해 이해가 쉽지 않네요. 어떻게 자동으로 제네릭에 두개를 입력해놨는데 그중 하나를 가져올 수 있는건지 코드팩토리 디스코드에 질문하면 더욱 빠르게 질문을 받아 볼 수 있습니다![코드팩토리 디스코드]https://bit.ly/3HzRzUM - 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
[js section07-2-2] 타이머 값 변경에 대해서
if(타이머 === "아직실행안함") 상태에서스크롤퍼센트가 >= 0.7 이면 타이머 값을 다른 값으로 변경해주어야타이머 = setTimeout(()=>{타이머="아직실행안함"},1000)이 코드로 스로틀링 되는게 아닌가요?영상에서는 타이머 값을 다른 값으로 변경해주지 않는데 이러면 타이머 = setTimeout(()=>{타이머="아직실행안함"},1000)이 코드를 추가하기 전과 같지 않나요?
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
이 강좌를 수강 하면 게시판을 만들수 있나요?
강좌 목록에는 페이징 게시글 관련사항이 있는데 Db와 연결해서게시판을 만들 수 있나요
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
위에 적으신 _testProvider는 지워도 상관이 없다는 뜻이겠죠?
_testProvider 와 gState가 같은 코드고 아래 코드가 위를 대신한다는 뜻이니 위는 지워도 되겠죠? 코드팩토리 디스코드에 질문하면 더욱 빠르게 질문을 받아 볼 수 있습니다![코드팩토리 디스코드]https://bit.ly/3HzRzUM - 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
강의자료가 안뜹니다
강의 자료가 있는 항목을 누르면이렇게 아무것도 뜨지 않습니다 ㅜ
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
백엔드도 '완벽한' 시리즈 코스가 나오나요?
백엔드도 나온다면 완벽한 시리즈로 듣고 싶어서요
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
질문드립니다
안녕하세요,수업 잘 듣고 따라가고 있습니다~~!! 다름이 아니라 , 아무래도 graphQL를 이용한것보다 취직하고싶은 회사에서 대부분REST API를 사용하는거같아 혹시 fetch 또는 axios를 사용하는 방법은 강의에 추가할 계획이 없으실까요?그리고 nextjs에서는 axios를 사용하는 대신에 fetch를 사용하는것이 맞을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
안녕하세요
안녕하세요,혹시 최초 프로젝트 생성할때, nextjs15버전으로 설정되었는데 괜찮을까요?14로 다운그레이드 해야할까요?
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
강의 자료 내용 확인 부탁드립니다.
안녕하세요. 수강생 입니다. 좋은 강의 잘 수강하면서 열심히 공부하고 있습니다.노션 페이지 내용 관련으로 문의드립니다.[입문] 시작은 프리캠프 - 섹션 3 CSS의 기본과 싸이월드 실습 1CSS 사용방법 3가지 예시 이미지 중 해당 내용들에 대한 이미지가 이상해문의 남깁니다. 감사합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
강의 자료 내용 맞는지 확인 부탁드립니다.
[입문] 시작은 프리캠프 - 섹션 2 HTML과 기술스택 이해하기 노션 페이지 내용 중 종속태그 예시 부분의 이미지에 태그 내용은 없고 글자만 표기되어 있습니다. 이 부분이 오류인지 확인 부탁드립니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Provider 내에 Provider 2개를 이용할 때 화면 업데이트 궁금한점.
김치,라면,삼겹살 등등의 값을 바꾼뒤에 filter 를 하면 가끔씩 필터가 안되는 아이들이 보이는 문제가 왜 발생되는지 궁금합니다! 강의 영상에서도 보였구요, 두 번째로는, toggleHasBought() 로 값을 변경하면 화면이 다시 그려지는데 왜 필터는 적용되지 않는지 이유도 알고싶습니다!
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Flutter 중급강의 소스코드는 링크는 어디에 있는 건가요?
Flutter 중급강의 소스코드는 링크는 어디에 있는 건가요? [강의 소개]에서도 없고 [기본 UI 작업하기] 강의 듣고 있는데 그런 설명없이 바로 진행되네요.초급 강의에서는 초반에 바로 말씀해주셔서 좋았는데 아쉽네요.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
마지막 xxx
강의 마지막 xxx는 빈공간 인건가요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Gorouter 메인함수 호출관련 질문
Gorouter를 활용하여class _App extends ConsumerWidget { const _App({Key? key}) : super(key: key); @override Widget build(BuildContext context,WidgetRef ref) { final router = ref.watch(routerProvider); return MaterialApp.router( // 시스템 설정에 따른 Theme // themeMode: ThemeMode.system, theme: TAppTheme.lightTheme, // darkTheme: TAppTheme.darkTheme, debugShowCheckedModeBanner: false, routerDelegate: router.routerDelegate, routeInformationParser: router.routeInformationParser, routeInformationProvider: router.routeInformationProvider, ); } }final routerProvider = Provider<GoRouter>((ref){ final provider = ref.watch(authProvider); return GoRouter( routes: provider.routes, initialLocation: '/splash', refreshListenable: provider, redirect: provider.redirectLogic ); }); 위와 같이 메인함수를 호출하고 있습니다. 여기서 푸쉬 알림을 받을때 특정 경로로 이동하게 하고 싶다면 GoRouter의 initiallocation을 활용해서 특정 경로로 보내야할거같은데 스플래시화면에서 로그인 검증하여 로그인 되어있다면 특정경로로 이동하고 로그인 안되어있다면 특정경로를 이동하지않고 로그인화면으로 이동하고싶은데 방법을 잘 모르겠습니다
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
paginate() 에 대한 질문입니다.
void paginate({ int fetchCount = 20, // 추가로 데이터 더 가져오기 // true = 더 가져오기 // false = 새로고침 bool fetchMore = false, // 강제로 다시 로딩하기 // true - CursorPaginationLoading() bool forceRefetch = false, }) async { // 5가지 가능성 // State의 상태 // 1) CursorPagination - 정상적으로 데이터가 있는 상태 // 2) CursorPaginationLoading - 데이터 로딩중(현재 캐시 없음 // 3) CursorPaginationError = 에러가 있는 상태 // 4) CursorPaginationRefetching = 첫번째 페이지부터 다시 데이터를 가져올때 // 5) CursorPaginationFetchMore - 추가 데이터를 paginate 해오라는 요청을 받았을때 // 바로 반환하는 상황 // 1) hasMore == false(기존 상태에서 이미 다음 데이터가 없다는 값을 들고 있다면) // 2) 로딩중 - fetchMore : true // fetchMore : false - 새로고침의 의도가 있음. try { if (state is CursorPagination && !forceRefetch) { final pState = state as CursorPagination; if (!pState.meta.hasMore) { return; } } final isLoading = state is CursorPaginationLoading; final isRefetching = state is CursorPaginationRefetching; final isFetchingMore = state is CursorPaginationFetchingMore; if (fetchMore && (isLoading || isRefetching || isFetchingMore)) { return; } // PaginationParams 생성 PaginationParams paginationParams = PaginationParams( count: fetchCount, ); // fetchMore if (fetchMore) { final pState = state as CursorPagination; state = CursorPaginationFetchingMore( meta: pState.meta, data: pState.data, ); paginationParams = paginationParams.copyWith( after: pState.data.last.id, ); } final resp = await repository.paginate( paginationParams: paginationParams, ); if (state is CursorPaginationFetchingMore) { final pState = state as CursorPaginationFetchingMore; // 기존 데이터에 새로운 데이터 추가 state = resp.copyWith(data: [ ...pState.data, ...resp.data, ]); } else { state = resp; } } catch (e) { state = CursorPaginationError(message: '데이터를 가져오지 못했습니다.'); } } 이부분이 있는데왜 하위의 fetchMore의 else문에서 또 조건을 걸어놓는지 궁금합니다. // fetchMore if (fetchMore) { final pState = state as CursorPagination; state = CursorPaginationFetchingMore( meta: pState.meta, data: pState.data, ); paginationParams = paginationParams.copyWith( after: pState.data.last.id, ); } // 데이터를 처음부터 가져오는 상황 else { // 만약 데이터가 있는 상황이라면 기존 데이터 보존한 채로 Fetch(API 요청)을 진행 if (state is CursorPagination && !forceRefetch) { final pState = state as CursorPagination; state = CursorPaginationRefetching( meta: pState.meta, data: pState.data, ); } else { state = CursorPaginationLoading(); } }
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
컨텍스트에 대한 질문
강의 보면 로그인 스크린의 빌드 컨텍스트 내부에 storage를 선언하셨는데, class _LoginScreenState extends State<LoginScreen> { String user = ""; String password = ""; @override Widget build(BuildContext context) { final storage = FlutterSecureStorage(); final dio = Dio(); final emulatorIp = '10.0.2.2:3000'; final simulatorIp = '127.0.0.1:3000'; final ip = Platform.isIOS ? simulatorIp : emulatorIp; return ...; } } 이 부분에서 왜 빌드컨텍스트 내부에 작성했는지 궁금합니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
객체 안에 객체가 있을때 모델링을
final List<Map<String,dynamic> products; 위와 같이 진행한다면factory RestaurantDetailModel.fromJson({ required Map<String, dynamic> json, }) { return RestaurantDetailModel( id: json['id'], name: json['name'], thumbUrl: 'http://$ip${json['thumbUrl']}', tags: List<String>.from(json['tags']), priceRange: RestaurantPriceRange.values.firstWhere( (element) => element.name == json['priceRange'], ), ratings: json['ratings'], ratingsCount: json['ratingsCount'], deliveryTime: json['deliveryTime'], deliveryFee: json['deliveryFee'], detail: json['detail'], products: List<Map<String, dynamic>>.from(json['products']), ); }fromJson 도 위와 같이 변경될 것 같은데, 이런 방식은 비효율적이거나 권장되지 않는 방식인가요?객체 안의 객체를 따로 모델링 하는 이유는 객체 안의 객체를 인스턴스화해서 재사용하는데 목적이 있는 건가요? 수업때 설명한 방식은 List 안에 Map 형태의 키값이 정해지지 않아 데이터 추출이 번거로워질 수 있다고 생각하면 되나요?
-
해결됨[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
dio 네트워크 에러
강의를 진행하던 도중 재실행을 했더니 갑작스럽게E/flutter ( 7367): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DioException [connection timeout]: The request connection took longer than 0:00:00.000000 and it was aborted. To get rid of this exception, try raising the RequestOptions.connectTimeout above the duration of 0:00:00.000000 or improve the response time of the server.E/flutter ( 7367): Error: SocketException: Connection timed out (OS Error: Connection timed out, errno = 110), address = 192.168.1.106, port = 39308E/flutter ( 7367): #0 DioMixin.fetch (package:dio/src/dio_mixin.dart:519:7)E/flutter ( 7367): <asynchronous suspension>E/flutter ( 7367): #1 LoginScreenState.build.<anonymous closure> (package:delivery/user/view/loginscreen.dart:77:36)E/flutter ( 7367): <asynchronous suspension>E/flutter ( 7367):dio의 연결초과 에러라고 뜨는데 해결방법을 모르겠습니다.잘 진행하다가 갑자기 이렇게 되버려서... 77번째줄 코드는 아래와 같습니다. final resp = await dio.post( 'http://ip/auth/login', options: Options( headers: { 'authorization': 'Basic $token', }, ), );
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
이 부분에서 Error: The argument type 'RestaurantDetailModel' can't be assigned to the parameter type 'RestaurantModel'.
import 'dart:convert'; import 'dart:async'; import 'package:colorfactor/common/const/data.dart'; import 'package:colorfactor/common/layout/default_layout.dart'; import 'package:colorfactor/product/component/product_card.dart'; import 'package:colorfactor/restaurant//component/RestaurantCard.dart'; import 'package:colorfactor/restaurant/model/restaurant_detail_model.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; class RestaurantDetailScreen extends StatelessWidget { final String id; const RestaurantDetailScreen({super.key, required this.id}); Future<Map<String, dynamic>> getRestaurantDetail() async { final dio = Dio(); final accessToken = await storage.read(key: ACCESS_TOKEN_KEY); final resp = await dio.get('http://$ip/restaurant/$id', options: Options( headers: { 'authorization': 'Bearer $accessToken' }, ), ); return resp.data; } @override Widget build(BuildContext context) { return DefaultLayout( title: '불타는 덕볶이', child: FutureBuilder<Map<String, dynamic>>( future: getRestaurantDetail(), builder: (_, AsyncSnapshot<Map<String, dynamic>> snapshot) { print(snapshot.data); if (!snapshot.hasData) { return Container(); } final item = RestaurantDetailModel.fromJson( json: snapshot.data!, ); return CustomScrollView( slivers: [ renderTop( model: item, ), renderLabel(), renderProducts(), ], ); } ), ); } SliverPadding renderLabel() { return SliverPadding( padding: EdgeInsets.symmetric(horizontal: 16), sliver: SliverToBoxAdapter( child: Text( '메뉴', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),), ), ); } renderProducts() { return SliverPadding( padding: EdgeInsets.symmetric(horizontal: 16), sliver: SliverList( delegate: SliverChildBuilderDelegate((context, index) { return Padding( padding: const EdgeInsets.only(top: 16.0), child: ProductCard(), ); }, childCount: 10, ), ), ); } SliverToBoxAdapter renderTop({ required RestaurantDetailModel model, }) { return SliverToBoxAdapter( child: RestaurantCard.fromModel( model: model, isDetail: true, ), ); } }이 강의 진행에서 SliverToBoxAdapter renderTop({ required RestaurantDetailModel model, }) { return SliverToBoxAdapter( child: RestaurantCard.fromModel( model: model, isDetail: true, ), ); } }이 부분에서 Error: The argument type 'RestaurantDetailModel' can't be assigned to the parameter type 'RestaurantModel'.이 에러가 뜹니다. 구조를 다시 따라가서 봐도 문제가 없는것 같은데, 아직 이해도가 낮아서 그런지 Detail모델이 왜 Model에 대입되는지가 이해가 안됩니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
resp.data; 에러
import 'dart:convert'; import 'dart:async'; import 'package:colorfactor/common/const/data.dart'; import 'package:colorfactor/common/layout/default_layout.dart'; import 'package:colorfactor/product/component/product_card.dart'; import 'package:colorfactor/restaurant//component/CourtCard.dart'; import 'package:colorfactor/restaurant/model/restaurant_detail_model.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; class RestaurantDetailScreen extends StatelessWidget { final String id; const RestaurantDetailScreen({super.key, required this.id}); Future<Map<String, dynamic>> getRestaurantDetail() async { final dio = Dio(); final accessToken = await storage.read(key: ACCESS_TOKEN_KEY); final resp = dio.get('http://$ip/restaurant/$id', options: Options( headers: { 'authorization' : 'Bearer $accessToken' }, ), ); return resp.data; } @override Widget build(BuildContext context) { return DefaultLayout( title: '불타는 덕볶이', child: FutureBuilder<Map<String, dynamic>>( future: getRestaurantDetail(), builder: (_, AsyncSnapshot<Map<String, dynamic>> snapshot){ print(snapshot.data); if(!snapshot.hasData){ return Container(); } final item = RestaurantDetailModel.fromJson( json: snapshot.data!, ); return CustomScrollView( slivers: [ renderTop(), renderLabel(), renderProducts(), ], ); } ), ); } SliverPadding renderLabel(){ return SliverPadding( padding: EdgeInsets.symmetric(horizontal: 16), sliver: SliverToBoxAdapter( child: Text('메뉴', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),), ), ); } renderProducts(){ return SliverPadding( padding: EdgeInsets.symmetric(horizontal: 16), sliver: SliverList( delegate: SliverChildBuilderDelegate((context, index){ return Padding( padding: const EdgeInsets.only(top: 16.0), child: ProductCard(), ); }, childCount: 10, ), ), ); } SliverToBoxAdapter renderTop(){ return SliverToBoxAdapter( child: RestaurantCard( image: Image.asset('asset/img/2.jpg'), name: '불떡', tags: ['떡복이','맛다','치즈'], ratings: 4.5, ratingsCount: 100, distanceRange: 10, courtFee: 4000, isDetail: true, detail: '맛있는 떡복이', ), ); } }return resp.data; 부분에서 아래와 같이Error: The getter 'data' isn't defined for the class 'Future<Response<dynamic>>'.계속 에러를 반환하는데 도무지 이유를 모르겠습니다.