我正在尝试从本地存储获取数据并使用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
请帮我解决这个错误...
您正在尝试将字符串解码为 Map
_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()));
}
}