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

Hyunsang-Coder님의 프로필 이미지

작성한 질문수

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

서버 세팅하기

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

23.12.21 01:22 작성

·

176

·

수정됨

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시간 넘게 씨름 중인데 도움 주시면 감사하겠습니다!

답변 3

0

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

2023. 12. 21. 12:22

안녕하세요!

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

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

감사합니다!

Hyunsang-Coder님의 프로필 이미지

2023. 12. 24. 16:22

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

0

Hyunsang-Coder님의 프로필 이미지

2023. 12. 21. 06:59

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

0

Hyunsang-Coder님의 프로필 이미지

2023. 12. 21. 01:53

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