묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
data.utils.dart 파일 수정 후에도 에러가 발생합니다.
안녕하세요, 개발 초급자로 따라 가기 버거운 가운데, Pagination 일반화까지 잘 따라 온 것 같은데, 사소한(?) 에러에 봉착했네요. Rating Pagination 강의에서 Pagination 일반화 후 RatingModel 출력 결과를 확인하는 가운데, data.utils.dart 파일에서 listPathsToUrls 함수의 매개변수를 List<String>에서 List로 변경해 주면 에러가 사라지는 것으로 확인해 주셨는데요.저는 똑같이 수정 후 build까지 해 주었는데, 아래와 같은 에러가 발생합니다.어디가 잘못된 걸까요?
-
해결됨[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
FlutterSecureStorage() 에서 const 선언
안녕하세요, 강의 잘 보고 있습니다.초급 후 중급으로 넘어가니 서버/클라이언트의 관계까지 고려해야 하고 배워야 할 것들이 산더미 처럼 넘쳐 나네요...토큰 선언시:const ACCESS_TOKEN_KEY = 'ACCESS_TOKEN'; const REFRESH_TOKEN_KEY = 'REFRESH_TOKEN';const로 하셨는데...RunTime 시 ID/ PW를 제대로 입력시 토근을 받아와서 저장하는 코드입니다.await storage.write(key: REFRESH_TOKEN_KEY, value: refreshToken); await storage.write(key: ACCESS_TOKEN_KEY, value: accessToken); 궁금한 것은 일반변수로 선언해야 될 것같은데요..FlutterSecureStorage()의 특정한 기능이 있는 것일까요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
dio 패키지는 redirect 처리를 하기 어렵나요?
Node.js express 로 라우터를 설정해 다음과 같은 코드로 http 통신을 했습니다/api/test1 주소의 post 라우터에서 /api/test2 주소의 post 라우터로 redirect 되는 통신을 테스트 해보았습니다 onPressed: () async { var res = await http.post(Uri.parse("$uri/api/test1"), headers: <String, String>{ 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode( { "key1": "1000", }, )); if (res.statusCode == 307) { var newURL = res.headers["location"]; print(res.body); res = await http.post(Uri.parse("$uri$newURL"), headers: <String, String>{ 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode( { "key1": "1000", }, )); print(res.body); } else { var data = res.body; print(data); } },테스트 결과 제가 데이터를 올바르게 전송할 수 있었습니다 그리고 이번에 선생님의 강의를 듣고 dio라는 패키지를 알게되어서 dio 패키지를 통해서 똑같은 통신 테스트를 해 보았습니다 onPressed: () async { final dio = Dio(BaseOptions( contentType: "application/json", followRedirects: false, maxRedirects: 5, )); final url = "$uri/api/test1"; final body = {'key1': '1000'}; final headers = {'Content-Type': 'application/json'}; try { Response res = await dio.post( url, data: body, ); if (res.statusCode == 307) { final redirectUrl = res.headers.value("location"); final redirectRes = await dio.post( redirectUrl!, data: body, options: Options( headers: headers, method: "POST", ), ); print(redirectRes.data); } else { final data = res.data; print(data); } } catch (e) { print("error 발생 $e"); } },followRedirects 을 true 로 해도 307 코드를 해결하지는 못하는것 같습니다 flutter: error 발생 DioError [DioErrorType.response]: Http status error [307]어떻게 dio 패키지로 redirect 를 처리 할 수 있을까요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
_RestaurantRepositor 에러
코드 제네레이션을 해도 도대체 무슨에러인지 모르겟어서 에러메세지랑 g파일까지 올려봅니다 도와주세요 ㅠㅠerror: The redirected constructor '_RestaurantRepository Function(Dio, {String? baseUrl})' has incompatible parameters with 'RestaurantRepository Function(Dio, {String baseurl})'. (redirect_to_invalid_function_type at [actual] lib\restaurant\repository\restaurant_repository.dart:13)
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
initState 에서 provider.read 를 해서 초기 데이타를 가져오고 싶은데 가능 한지요?
안녕하세요.중급 강의 잘 듣고 많은 도움이 되었습니다.한가지 질문이 있는데요. view의 initState 에서 provider read 를 통해 데이타를 가져와 state 에 넣어주고,View 의 widget tree 내에서 watch 해서 쓰고 싶습니다.아래처럼 provider.read 를 쓸 수는 없을까요? 꼭 onClick 같은 이벤트 내에서만 쓸 수 있는 것인가요? @overridevoid initState() {// TODO: implement initStatesuper.initState();ref.read(floorNoProvider.notifier).getData();} 그럴 경우 아래와 같은 에러가 발생하는데요.Tried to modify a provider while the widget tree was building. 방법이 없을까요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
초급 중급 마무리한 학생입니다.. 파베관련 질문 하나만 받아주실 수 있을까요
코팩님 덕분에 초급 중급 강의 열심히 듣고 파베 듣고 있습니다.비록 강의와는 무관하지만.. 하루종일 구글링하다가 지쳐서 부득이하게 코팩님께 질문드립니다.죄송합니다.파베 cli로 연동하고 xcode 를 실행하면 위와같이 계속 Module 'firebase_core' not found에러가 납니다. pod 재설치도 해보고 수동으로도 연동해보고 별짓 다해봐도 안되네요... 도움좀 주시면 감사드리겠습니다. + 저거 Module 'firebase_core' not found이 에러만 나는 게 아니라 등록한 firebase package 전부다 인식이 안되는 듯 합니다...
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Pagination 질문드립니다
안녕하세요. pagination관련해서 궁금한 게있습니다.저는 백엔드를 직접 구축하고강의를 수강하고있는데요,Order를 생성하는 provider Ordrer 리스트를 조회하는 Pagination (강의에서 진행한 방식의 Pagination Model)제가 아직 상태관리에 이해가 부족해서 그런지, Order가 생성되면List<OrderModel>에 맞추어 데이터를 담아두고 생성될 때마다 페지네이션을 상속받는 데이터 리스트들이 업데이트 돼야하지 않나하는 생각이 드는데 그렇개 작동되지 않더라구요Order를 생성하고 나서order 리스트를 볼 수 있는 페이지에 오면데이터가 업데이트 되지않습니다.어떻게해야 Creat이후 Read가 업데이트가 되나요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
레이아웃에 대해서 궁금한 질문!
안녕하세요. 공통 레이아웃으로 앱바, 네비게이션 등을 프롭스(?)로 받아서 하나의 레이아웃 파일로 여러 파일, 페이지에서 사용하는거랑타입별로 예를들어서 앱바있는 타입의 레이아웃, 앱바+바텀네비게이션 있는 타입의 레이아웃 등등... 이런식으로 파일을 여러개 레이아웃을 만들어놓고 사용하는거랑 뭔가 최적화 적으로 차이가 있을까요? 갑자기 궁금합니당
-
해결됨[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
강의에 적용된 디자인 패턴이 뭔가요??
flutter 앱을 유지보수하기 쉽게 개발하기 위해 디자인 패턴을을 쓰는데 아직까지 구분하는게 어렵습니다.혹시 강의에서도 디자인 패턴을 고려해서 앱을 만드셨는지 궁금해서 질문을 드립니다! 그리고 flutter 에 잘 맞는 디자인 패턴은 뭔지도 궁금합니다!!
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
네스팅 방식으로 goRouter Go를 사용할때, 앱바타이틀이 정상적으로 표시되지 않는 문제
GoRouter 초반부를 듣고 있는데, 제목과 같이 앱바타이틀이 정상적으로 표시되지 않는 문제를 겪고 있습니다.Screen Three 로 이동했을때 앱바의 타이틀은/one/two/three 로 표기가 되나,뒤로가기를 눌렀을때 홈으로 이동할때까지 그 상태 그대로 /one/two/three 가 유지되다가 홈에서 / 로 표시가 됩니다.OneScreen, TwoScreen, ThreeScreen 별로 각각 텍스트로 one, two, three 라고 입력해서 확인해본결과,뒤로가기 할때마다 three 에서 출발해서 two, one 으로 화면에 잘 뜨는 것으로 보아 페이지 이동은 정상적으로 이루어지는 것 같습니다. 아래는 default_layout.dart 입니다.class DefaultLayout extends StatelessWidget { final Widget body; const DefaultLayout({ Key? key, required this.body, }) : super(key: key); @override Widget build(BuildContext context) { final router = GoRouter.of(context); return Scaffold( appBar: AppBar( title: Text( router.location, ), ), body: Padding( padding: const EdgeInsets.symmetric( horizontal: 16.0, ), child: body, ), ); } } main.dartvoid main() { runApp(_App()); } class _App extends StatelessWidget { _App({Key? key}) : super(key: key); final GoRouter _router = GoRouter( initialLocation: '/', routes: [ GoRoute( path: '/', builder: (context, state) => const HomeScreen(), routes: [ GoRoute( path: 'one', builder: (context, state) => const OneScreen(), routes: [ // http://.../one/two GoRoute( path: 'two', builder: (context, state) => const TwoScreen(), routes: [ // http://.../one/two/three GoRoute( path: 'three', builder: (context, state) => const ThreeScreen(), ), ], ) ], ), ], ), // http://..../one // http://..../two // GoRoute( // path: '/one', // builder: (context, state) => const OneScreen(), // ), ], ); @override Widget build(BuildContext context) { return MaterialApp.router( theme: ThemeData(useMaterial3: true), // uri string 을 상태 및 go router 에서 사용할 수 있는 형태로 변환해주는 함수(자동) routeInformationParser: _router.routeInformationParser, // 위에서 변경된 값으로 실제 어떤 route 를 보여줄지 정하는 함수(자동) routerDelegate: _router.routerDelegate, // route 정보를 전달하는 함수(자동) routeInformationProvider: _router.routeInformationProvider, ); } } home_screen.dartclass HomeScreen extends StatelessWidget { const HomeScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return DefaultLayout( body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { context.go('/one'); }, child: const Text('go to OneScreen'), ), ElevatedButton( onPressed: () { context.go('/one/two/three'); }, child: const Text('go to ThreeScreen'), ), ], ), ); } } 3_screen.dartclass ThreeScreen extends StatelessWidget { const ThreeScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return DefaultLayout( body: Column( children: const [Text('three')], ), ); } } 정도로 참고 코드를 올렸습니다.goRouter 버전은 4.2.2 로 강의의 버전과 맞춰서 진행중입니다.
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
GoRouter return이 안됩니다.
final routeProvider = Provider<GoRouter>( (ref) { print('1 : routeProvider 실행'); final authState = ref.watch(authProvider); print('1 : authState is ${authState}'); print('------GoRouter return!!-------'); return GoRouter( initialLocation: '/', routes: authState.route, refreshListenable: authState, redirect: authState.redirect, ); }, ); 위에서 return GoRouter하는 순간 위와 같은 오류가 발생하네요...ㅠ몇 시간을 고민해도 도저히 모르겠습니다.복기하면서 나는 오류인데, 그 전에 강의 보면서 해놓은거랑 똑같이해도 이것만 오류가 나네요... 도와주세요
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
UserModel 에서는 IModelWithId를 implements하지 않는 이유가 있나요?
pagination을 할때 사용할 모델들에 IModleWIthId를 implements 한다고 하셨는데, UserModel 에서는 어떤 이유가 있어서 하지 않으신건가요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
서버쪽 /user/me api에서 에러가 나서 확인해보니..
서버쪽 bearer-token.guard.ts 쪽에서 토큰으로 유저정보 만드는 부분에 아래처럼 sub으로 유저정보를 검색하는데 sub이 user id이더라구요.. 그래서 user 값이 제대로 조회가 안되서 에러가 발생했었습니다.request.user = await this.userService.findByUsername(payload.sub);일단 payload.username으로 검색하게 하니 잘되는것 같습니다~
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
[에러] GoRouter 적용, 401 에러가 뜹니다
안녕하세요/data big작성일 22.09.26 18:06 조회수 28GoRouter 프로젝트에 적용하기 / Authentication 마무리하기 강의 단계에서서버에서 401 Unauthorized 에러가 발생합니다. 라고 글이 검색되었는데, 저도 비슷합니다.다만 저는 로컬호스트/유저/미 로그를 클릭하면토큰이 없다고 나오고요,부랴부랴 포스트맨에서 로그인 포스트 해보면리프레시토큰/억세스토큰 잘 받아옵니다다만 그 이후에 auth/token을 하면 잘못된 토큰이라고 나오네요.저 역시 첫 에러는 user_me_repository.g.dart,두번째로 가리키는 곳은 user_me_provider 입니다final resp = await repository.getMe(); 네요강사님 코드와 일치하는 것 확인했고, 혹시나 싶어서강사님 코드 긁어서 붙여넣기도 해봤습니다.저 역시 아이폰 시뮬레이터에선 splash_screen에서 멈추고무한 프로그레스 인디케이터만 돌고 있습니다. 추가합니다(꼼수로 /splash가 아니라 /restaurant로 initialLocation 변경한 다음에미리 만들어놓은 로그아웃 탭으로 가서 로그아웃하고 다시 로그인 하니 되네요..그리고 다시 /splash 원상복구시키니 됩니다.다만 포스트맨에서는 여전히 잘못된 토큰이라고 나오네요.고라우터 버전은 ^4.4.2 으로 맞춰놓고 따라가고 있습니다) 또 추가합니다맨 위에서 언급한 다른 질문글과 에러 로그는 같은데,이런 식?으로 우회하면 되는 건가요? 그냥 순간 안맞는 경우가 있는 건가요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
ref.read.update // state + 1
아래 두 코드 차이가 있나요?2번 코드처럼 사용해도 상관은 없는건가요?1. ref.read(numberProvider.notifier).update( (state) => state + 1, ); 2. ref.read(numberProvider.notifier).state = ref.read(numberProvider.notifier).state + 1;
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
typedef itemBuilder 제네릭 관련 질문이 있습니다.
아래처럼 itemBuilder를 넣어봤는데요, Widget build(BuildContext context) { return PaginationListView( provider: restaurantNotifierProvider, itemBuilder: itemBuilder<RestaurantModel>); } Widget itemBuilder<T extends IModelWithId>(BuildContext context, int index, T t) { t as RestaurantModel; return GestureDetector( onTap: () { Navigator.of(context).push( MaterialPageRoute( builder: (_) { return RestaurantDetailScreen( id: t.id, ); }, ), ); }, child: RestaurantCard.fromModel( restaurantModel: t, ), ); } }아래와 같은 에러가 나옵니다type '(BuildContext, int, RestaurantModel) => Widget' is not a subtype of type '(BuildContext, int, IModelWithId) => Widget'근데, RestaurantModel implements IModelWithId라고 해주었으니 상속관계가 있는데 왜 subtype이 아니라는걸까요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
[상태관리] Riverpod을 쓰신 이유가 있으신가요?
안녕하세요 상태관리 라이브러리 관하여 여쭤볼게 있습니다.상태관리 라이브러리가 많은데 그중 riverpod을 쓰시는 이유가 있으신가요?다른 상태관리 라이브러리 (Provider, Bloc, Get 등)을 사용해도 강의에 나온것과 같은 기능, 같은 패턴으로 구현할수 있나요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
Dio 질문드립니다.!
Dio에 interceptor을 붙여서 토큰 만료일때 갱신을 해주는데, Future.wait 로 병렬적으로 요청할때 연속된 요청에 대해서는 어떻게 처리되나요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
CursorPagination 캐스팅 관련 문의
죄송하지만, 어제 질문을 남겼는데 제가 제대로 궁금한 사항을 전달하지 못한 거 같아 다시 질문드립니다.paginate함수에서 왜 꼭 final pState = state as CursorPaginationFetchingMore<T>; 해주어야만 하는지 잘 이해를 못하겠습니다. 강의에서 처럼,final resp = await repository.paginate(paginationParams: paginationParams); if (state is CursorPaginationFetchingMore) { final pState = state as CursorPaginationFetchingMore<T>; // 기존 데이터에 새로운 데이터 추가 state = resp.copyWith( data: [ ...pState.data, ...resp.data, ], );이 아닌, final resp = await repository.paginate(paginationParams: paginationParams); if (state is CursorPaginationFetchingMore) { state as CursorPaginationFetchingMore<T>; // 기존 데이터에 새로운 데이터 추가 state = resp.copyWith( data: [ ...state.data, ...resp.data, ], );으로 하게 되면 왜 data가 자동완성이 안되는 걸까요? state의 상태를 CursorPaginationBase로만 인식을 해서 안되던데, CursorPaginationFetchingMore extends CursorPaginationBase를 했으니, state as CursorPagination<T>이라고 해도 .data를 인식해야 하는거 아닌가요?
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
CursorPagination 캐시팅 관련 문의
paginate 함수에서, final pState = state as CursorPagination 하는 분에서요,state as CursorPagination 하면 state.data라고 자동완성이 안되던데 왜 그런가요?데이터타입을 CursorPaginationBase로만 인식하던데 as CursorPagination을하면 확실한 다운캐스팅에선 data가 인식 되어야 맞는거 아닌가요?