类型错误:“String”类型不是“Map<String, dynamic>”类型的子类型

问题描述 投票:0回答:1

我正在尝试从本地存储获取数据并使用flutter_bloc将其显示在屏幕上,但我收到错误“类型‘String’不是类型‘Map’的子类型”。我已经检查过,但找不到解决方案。

有人帮我解决这个错误...

下面是我的代码...

我已经在 main.dart 文件中添加了 BlockProvider。

void main() async {
  runApp(
    MultiBlocProvider(
      providers: [
        BlocProvider<ResumeTemplatePreviewBloc>(
            create: (context) => ResumeTemplatePreviewBloc()),
      ],
      child: const MaterialApp(
        home: ResumeTempletePreview(isstart: true),
      ),
    ),
  );
}

resume_templete_preview_bloc.dart

class ResumeTemplatePreviewBloc
    extends Bloc<ResumeTemplatePreviewEvent, ResumeTemplatePreviewState> {
  ResumeTemplatePreviewBloc() : super(ResumeTemplatePreviewInitial()) {
    on<LoadResumeData>(_onLoadResumeData);
  }

  void _onLoadResumeData(
      LoadResumeData event, Emitter<ResumeTemplatePreviewState> emit) async {
    emit(ResumeTemplatePreviewLoading());
    try {
      final jsonString = window.localStorage['RESUMEDATA'];
      if (jsonString == null || jsonString.isEmpty) {
        throw Exception('No resume data found in local storage');
      }

      final Map<String, dynamic> resumeData = json.decode(jsonString);
      log("Decoded resume data: $resumeData");

      emit(ResumeTemplatePreviewLoaded(resumeData));
    } catch (e) {
      log(e.toString());
      emit(ResumeTemplatePreviewError(e.toString()));
    }
  }
}

resume_templete_preview_event.dart

import 'dart:typed_data';

import 'package:equatable/equatable.dart';

abstract class ResumeTemplatePreviewEvent extends Equatable {
  const ResumeTemplatePreviewEvent();

  @override
  List<Object> get props => [];
}

class LoadResumeData extends ResumeTemplatePreviewEvent {}

class DownloadResume extends ResumeTemplatePreviewEvent {
  final Uint8List capturedImage;

  const DownloadResume(this.capturedImage);

  @override
  List<Object> get props => [capturedImage];
}

resume_templete_preview_state.dart

import 'package:equatable/equatable.dart';

abstract class ResumeTemplatePreviewState extends Equatable {
  const ResumeTemplatePreviewState();

  @override
  List<Object> get props => [];
}

class ResumeTemplatePreviewInitial extends ResumeTemplatePreviewState {}

class ResumeTemplatePreviewLoading extends ResumeTemplatePreviewState {}

class ResumeTemplatePreviewLoaded extends ResumeTemplatePreviewState {
  final Map<String, dynamic> resumeData;

  const ResumeTemplatePreviewLoaded(this.resumeData);

  @override
  List<Object> get props => [resumeData];
}

class ResumeTemplatePreviewError extends ResumeTemplatePreviewState {
  final String message;

  const ResumeTemplatePreviewError(this.message);

  @override
  List<Object> get props => [message];
}

class ResumeDownloading extends ResumeTemplatePreviewState {}

class ResumeDownloaded extends ResumeTemplatePreviewState {}

class ResumeDownloadError extends ResumeTemplatePreviewState {
  final String message;

  const ResumeDownloadError(this.message);

  @override
  List<Object> get props => [message];
}

resume_templete_preview.dart

import 'dart:convert';
import 'dart:developer';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'dart:html';

import 'package:flutter/material.dart';
import 'package:quick_resume_creator/core/colors/app_colors.dart';
import 'package:quick_resume_creator/core/constants/dimens.dart';
import 'package:quick_resume_creator/models/education.dart';
import 'package:quick_resume_creator/models/employment.dart';
import 'package:quick_resume_creator/models/personal_skill.dart';
import 'package:quick_resume_creator/models/professional_skill.dart';
import 'package:quick_resume_creator/models/skill.dart';
import 'package:quick_resume_creator/screens/home_screen/home_screen.dart';
import 'package:quick_resume_creator/screens/resume_template/resume_template1.dart';
import 'package:quick_resume_creator/screens/resume_template/resume_template2.dart';
import 'package:quick_resume_creator/screens/resume_templete_preview/resume_templete_preview_bloc/resume_templete_preview_bloc.dart';
import 'package:quick_resume_creator/screens/resume_templete_preview/resume_templete_preview_bloc/resume_templete_preview_event.dart';
import 'package:quick_resume_creator/screens/resume_templete_preview/resume_templete_preview_bloc/resume_templete_preview_state.dart';

class ResumeTempletePreview extends StatefulWidget {
  final dynamic extra;
  final bool isstart;
  const ResumeTempletePreview({super.key, this.extra, required this.isstart});

  @override
  State<ResumeTempletePreview> createState() => _ResumeTempletePreviewState();
}

class _ResumeTempletePreviewState extends State<ResumeTempletePreview> {
  String resumeIndex = "";

  late ScrollController _scrollController;

  @override
  void initState() {
    _scrollController = ScrollController();
    _scrollController.addListener(() {
      setState(() {
        if (_scrollController.offset >= 300) {
          showBackToTopButton = true;
        } else {
          showBackToTopButton = false;
        }
      });
    });

    super.initState();

    context.read<ResumeTemplatePreviewBloc>().add(LoadResumeData());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: AppColors.authBgcolor,
        appBar: _buildappbar(),
        body: ListView(
          children: [
            Divider(color: AppColors.dividercolor, height: 1),
            buildSizedBoxH(50),
            BlocBuilder<ResumeTemplatePreviewBloc, ResumeTemplatePreviewState>(
              builder: (context, state) {
                if (state is ResumeTemplatePreviewLoading) {
                  log("state is ResumeTemplatePreviewLoading");
                  return const Center(child: CircularProgressIndicator());
                } else if (state is ResumeTemplatePreviewLoaded) {
                  log("state is ResumeTemplatePreviewLoaded");
                  resumeIndex = state.resumeData['id'] != null &&
                          state.resumeData['id'] != ""
                      ? state.resumeData['id'].toString()
                      : "1";
                } else if (state is ResumeTemplatePreviewError) {
                  log("state is ResumeTemplatePreviewError");
                  return Center(child: Text(state.message));
                }
                return getResumeTemplate(resumeIndex);
              },
            ),
          ],
        ));
  }

  Widget getResumeTemplate(String status) {
    switch (status) {
      case '1':
        return ResumeTemplate1(
          customerFirstNametext:
              window.localStorage['CUSTOMERFIRSTNAME'].toString(),
          customerLastNametext:
              window.localStorage['CUSTOMERLASTNAME'].toString(),
          customerProfileImageURL:
              window.localStorage['CUSTOMERPROFILEIMAGE'].toString(),
          customerProfessiontext:
              window.localStorage['CUSTOMERPROFESSION'].toString(),
          customerLocationtext:
              window.localStorage['CUSTOMERLOCATION'].toString(),
          customerWebsitetext:
              window.localStorage['CUSTOMERWEBSITE'].toString(),
          customerPhoneNotext:
              window.localStorage['CUSTOMERPHONENO'].toString(),
          customerEmailIDtext:
              window.localStorage['CUSTOMEREMAILID'].toString(),
          customerProfessionalSummarytext:
              window.localStorage['CUSTOMERPROFESSIONALSUMMARY'].toString(),
          customerEducationList:
              (jsonDecode(window.localStorage['CUSTOMEREDUCATIONLIST']!)
                      as List<dynamic>)
                  .map<Education>((item) => Education.fromJson(item))
                  .toList(),
          customerEmploymentList:
              (jsonDecode(window.localStorage['CUSTOMEREMPLOYMENTLIST']!)
                      as List<dynamic>)
                  .map<Employment>((item) => Employment.fromJson(item))
                  .toList(),
          customerProfessionalSkillList:
              (jsonDecode(window.localStorage['CUSTOMERPROFESSIONALSKILLLIST']!)
                      as List<dynamic>)
                  .map<ProfessionalSkill>(
                      (item) => ProfessionalSkill.fromJson(item))
                  .toList(),
          customerPersonalSkillList:
              (jsonDecode(window.localStorage['CUSTOMERPERSONALSKILLLIST']!)
                      as List<dynamic>)
                  .map<PersonalSkill>((item) => PersonalSkill.fromJson(item))
                  .toList(),
        );
      case '2':
        return ResumeTemplate2(
          customerFirstNametext:
              window.localStorage['CUSTOMERFIRSTNAME'].toString(),
          customerLastNametext:
              window.localStorage['CUSTOMERLASTNAME'].toString(),
          customerProfileImageURL:
              window.localStorage['CUSTOMERPROFILEIMAGE'].toString(),
          customerProfessiontext:
              window.localStorage['CUSTOMERPROFESSION'].toString(),
          customerLocationtext:
              window.localStorage['CUSTOMERLOCATION'].toString(),
          customerWebsitetext:
              window.localStorage['CUSTOMERWEBSITE'].toString(),
          customerPhoneNotext:
              window.localStorage['CUSTOMERPHONENO'].toString(),
          customerEmailIDtext:
              window.localStorage['CUSTOMEREMAILID'].toString(),
          customerProfessionalSummarytext:
              window.localStorage['CUSTOMERPROFESSIONALSUMMARY'].toString(),
          customerEducationList:
              (jsonDecode(window.localStorage['CUSTOMEREDUCATIONLIST']!)
                      as List<dynamic>)
                  .map<Education>((item) => Education.fromJson(item))
                  .toList(),
          customerEmploymentList:
              (jsonDecode(window.localStorage['CUSTOMEREMPLOYMENTLIST']!)
                      as List<dynamic>)
                  .map<Employment>((item) => Employment.fromJson(item))
                  .toList(),
          customerSkillList:
              (jsonDecode(window.localStorage['CUSTOMERSKILLLIST']!)
                      as List<dynamic>)
                  .map<Skill>((item) => Skill.fromJson(item))
                  .toList(),
        );
      default:
        return ResumeTemplate1(
          customerFirstNametext:
              window.localStorage['CUSTOMERFIRSTNAME'].toString(),
          customerLastNametext:
              window.localStorage['CUSTOMERLASTNAME'].toString(),
          customerProfileImageURL:
              window.localStorage['CUSTOMERPROFILEIMAGE'].toString(),
          customerProfessiontext:
              window.localStorage['CUSTOMERPROFESSION'].toString(),
          customerLocationtext:
              window.localStorage['CUSTOMERLOCATION'].toString(),
          customerWebsitetext:
              window.localStorage['CUSTOMERWEBSITE'].toString(),
          customerPhoneNotext:
              window.localStorage['CUSTOMERPHONENO'].toString(),
          customerEmailIDtext:
              window.localStorage['CUSTOMEREMAILID'].toString(),
          customerProfessionalSummarytext:
              window.localStorage['CUSTOMERPROFESSIONALSUMMARY'].toString(),
          customerEducationList:
              (jsonDecode(window.localStorage['CUSTOMEREDUCATIONLIST']!)
                      as List<dynamic>)
                  .map<Education>((item) => Education.fromJson(item))
                  .toList(),
          customerEmploymentList:
              (jsonDecode(window.localStorage['CUSTOMEREMPLOYMENTLIST']!)
                      as List<dynamic>)
                  .map<Employment>((item) => Employment.fromJson(item))
                  .toList(),
          customerProfessionalSkillList:
              (jsonDecode(window.localStorage['CUSTOMERPROFESSIONALSKILLLIST']!)
                      as List<dynamic>)
                  .map<ProfessionalSkill>(
                      (item) => ProfessionalSkill.fromJson(item))
                  .toList(),
          customerPersonalSkillList:
              (jsonDecode(window.localStorage['CUSTOMERPERSONALSKILLLIST']!)
                      as List<dynamic>)
                  .map<PersonalSkill>((item) => PersonalSkill.fromJson(item))
                  .toList(),
        );
    }
  }
}

这是我的调试控制台...

Restarted application in 244ms.
[log] TypeError: "{\"uid\":\"ryln8SHS9fg7cTE7sTdwS4dzmeH2\",\"id\":\"6\",\"resumeid\":\"fXFhqH02zX8iv8THRVB1\",\"customerFirstNametext\":\"Testing\",\"customerLastNametext\":\"Testing\",\"customerProfileImage\":\"https://firebasestorage.googleapis.com/v0/b/quick-resume-creator.appspot.com/o/profile_images%2Fryln8SHS9fg7cTE7sTdwS4dzmeH2%2FfXFhqH02zX8iv8THRVB1%2F1720696073185.jpg?alt=media&token=8c803ce4-4a98-43f2-b630-ccec214a317f\",\"customerProfessiontext\":\"Testing\",\"customerLocationtext\":\"Testing\",\"customerWebsitetext\":\"www.testing.com\",\"customerPhoneNotext\":\"7894561230\",\"customerEmailIDtext\":\"[email protected]\",\"customerProfessionalSummarytext\":\"TestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTestingTesting.\",\"customerEducationList\":[{\"university\":\"Testing\",\"degree\":\"Testing\",\"startDate\":\"Jul 2023\",\"endDate\":\"Jul 2033\"}],\"customerEmploymentList\":[{\"jobTitle\":\"Testing\",\"companyName\":\"Testing\",\"startDate\":\"Jul 2023\",\"endDate\":\"Jul 2025\",\"address\":\"Testing\"}],\"customerProfessionalSkillList\":[],\"customerPersonalSkillList\":[],\"customerSkillList\":[{\"skill\":\"Testing\",\"level\":60},{\"skill\":\"Testing\",\"level\":40},{\"skill\":\"Testing\",\"level\":40}],\"customerSkillLavel\":0}": type 'String' is not a subtype of type 'Map<String, dynamic>'
[log] state is ResumeTemplatePreviewError

请帮我解决这个错误...

flutter local-storage flutter-bloc
1个回答
0
投票

您正在尝试将字符串解码为 Map,但失败了,因为该字符串可能不是有效的 JSON 或未正确解码 尝试这个错误处理。

    _onLoadResumeData(LoadResumeData event, Emitter<ResumeTemplatePreviewState> emit) async {emit(ResumeTemplatePreviewLoading());
  try {
    final jsonString = window.localStorage['RESUMEDATA'];
    if (jsonString == null || jsonString.isEmpty) {
      throw Exception('No resume data found in local storage');
    }
    // Log the jsonString for debugging
    print("Retrieved resume data JSON: $jsonString");
    // Decode jsonString into Map<String, dynamic>
    final Map<String, dynamic> resumeData = json.decode(jsonString);
    // Log decoded resume data for debugging
    print("Decoded resume data: $resumeData");
    emit(ResumeTemplatePreviewLoaded(resumeData));
  } catch (e) {
    print("Error loading resume data: $e");
    emit(ResumeTemplatePreviewError(e.toString()));
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.