강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

Hyunsang-Coder님의 프로필 이미지
Hyunsang-Coder

작성한 질문수

[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!

서버 세팅하기

basketProvider에서 patchBasket 함수 호출 시 에러가 발생합니다

작성

·

324

·

수정됨

0

제 코드는 아래와 같고,

import 'package:advanced_app/product/model/product_model.dart';
import 'package:advanced_app/user/model/patch_basket_model.dart';
import 'package:advanced_app/user/model/basket_item_model.dart';
import 'package:advanced_app/user/repository/user_me_repository.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:collection/collection.dart';

final basketProvider = StateNotifierProvider<BasketProvider, List<BasketItemModel>>((ref) {
  final repository = ref.watch(userMeRepositoryProvider);
  return BasketProvider(repository: repository);
});

class BasketProvider extends StateNotifier<List<BasketItemModel>>{
  final UserMeRepository repository;

  BasketProvider({
    required this.repository,
}):super([]);

  Future<void> patchBasket () async {
    await repository.patchBasket(
        body: PatchBasketBody(
            basket: state.map(
                (e) => PatchBasketBodyBasket(
                    productID: e.product.id,
                    count: e.count))
            .toList())
    );

  }
  Future<void> addToBasket({
    required ProductModel product,}) async {
    // 1 아직 장바구니에 해당 상품이 없는 경우 -> 추가
    // 2 동일한 상품이 있는 경우 -> count +1

    final exists = state.firstWhereOrNull((e) => e.product.id == product.id) != null;

    if(exists){
      state = state
          .map(
              (e) => e.product.id == product.id
                  ? e.copyWith(count: e.count +1)
          : e
      ).toList();
    }else{
      state = [
        ...state,
        BasketItemModel(
            product: product,
            count:1)
      ];
    }

    await patchBasket();
  }

  Future<void> removeFromBasket({
  required ProductModel product,
    bool isDelete = false}) async{
    // isDelete면 count와 상관없이 삭제
    final exists = state.firstWhereOrNull((e) => e.product.id == product.id) != null;

    if(!exists){
      return;
    }
    // 이제 무조건 있는 경우
    final existingProduct = state.firstWhere((element) => element.product.id == product.id);
    
    // 1개 있는 경우 삭제 (해당하는 상품 빼고 리스트 만들어서 넣어 주는 방식)
    if (existingProduct.count == 1 || isDelete){
      state = state
          .where((e)
      => e.product.id != product.id)
          .toList();
    }
    else{
      // 2개 이상 있는 경우
      state = state
          .map((e) => e.product.id == product.id?
      e.copyWith(
          count: e.count -1) :
      e).toList();
    }
  }
}


에러 로그는 아래와 같습니다.
--------------
[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast

#0 $BasketItemModelFromJson (package:advancedapp/user/model/basket_item_model.g.dart:11:54)

#1 new BasketItemModel.fromJson (package:advanced_app/user/model/basket_item_model.dart:25:14)

#2 UserMeRepository.patchBasket.<anonymous closure> (package:advancedapp/user/repository/user_me_repository.g.dart:93:45)

#3 MappedListIterable.elementAt (dart:_internal/iterable.dart:415:31)

#4 ListIterator.moveNext (dart:_internal/iterable.dart:344:26)

#5 new GrowableList.ofEfficientLengthIterable (dart:core-patch/growable_array.dart:189:27)

#6 new GrowableList.of (dart:core-patch/growablearray.dart:150:28)

#7 new List.of (dart:core-patch/array_patch.dart:47:28)

#8 ListIterable.toList (dart:_internal/iterable.dart:214:7)

#9 UserMeRepository.patchBasket (package:advancedapp/user/repository/user_me_repository.g.dart:94:10)



Postman에서 get http://127.0.0.1:3000/user/me/basket 실행해 보면,

[ { "count": 1 } ]

처럼 product가 제대로 안들어가고 count 값만 들어가 있습니다.

jsonSerializable 문제인가 싶어서 모델들 다 체크해봤는데... 코드 제너레이션도 정상적으로 되는데... 뭐가 문제일까요? 이것 때문에 3시간 넘게 씨름 중인데 도움 주시면 감사하겠습니다!

퀴즈

71%나 틀려요. 한번 도전해보세요!

세션 기반 인증과 토큰 기반 인증 방식에서 사용자 정보 저장 방식의 주요 차이점은 무엇인가요?

세션은 클라이언트에, 토큰은 서버에 저장해요.

세션은 서버에, 토큰은 클라이언트에 저장해요.

세션은 데이터베이스에, 토큰은 메모리에 저장해요.

세션은 메모리에, 토큰은 데이터베이스에 저장해요.

답변 3

0

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

안녕하세요!

에러 메세지에서도 모델의 g파일을 가리키고 있습니다.

다음에 에러 메세지가 있을때는 꼭 에러 메세지의 정확한 위치로 이동해서 확인해보세요.

감사합니다!

넵! 그런데 에러 위치로 이동하고나서도 뭐가 문제인지 정확히 몰랐었네요.ㅜ 이번 실수로 field선언 할 때 json의 파일명이 완전히 같아야 한다는 걸 몸소 깨닫게 되어서 다시는 같은 실수를 반복할 일은 없을 것 같습니다 :)

0

자고 일어나서 맑은 정신으로 다시 보니 10분만에 문제가 해결되네요 ^^;; http요청 보낼 때 productId가 아니라 productID로 보내고 있었네요 ㅜㅜ 잠시나마 "혹시 서버나 코드에 문제가 있던 거 아닌가?"하고 의심했던 점 사과드립니다! 늘 좋은 강의 감사드립니다!!

0

try catch 해보면 "flutter: type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast" 이런 메시지가 발생합니다.

Hyunsang-Coder님의 프로필 이미지
Hyunsang-Coder

작성한 질문수

질문하기