skip to Main Content

I am trying to get data from local storage and display it on the screen using flutter_bloc, but I am getting the error "type ‘String’ is not a subtype of type ‘Map<String, dynamic>’". I have checked, but I cannot find a solution.

Someone help me to solve this error…

Below is my code…

And I have added BlockProvider in main.dart file.

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(),
        );
    }
  }
}

This is my Debug Console…

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

Please help me to solve this error…

2

Answers


  1. you’re trying to decode a string into a Map<String, dynamic>, but it’s failing because the string might not be valid JSON or is not being decoded correctly
    try this error-handling.

        _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()));
      }
    }
    
    Login or Signup to reply.
  2. Your jsonString contains " at the start and end, so if you are sure that the string starts and ends with " you need to trim it manually.

    try {
      String? jsonString = window.localStorage['RESUMEDATA'];
      if (jsonString == null || jsonString.isEmpty) {
        throw Exception('No resume data found in local storage');
      }
      if (jsonString.startsWith('"')){
         jsonString = jsonString.subString(1);
      }
      if (jsonString.endsWith('"')){
         jsonString = jsonString.subString(0, jsonString.length - 1);
      }
    
      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()));
    }
    

    Try with this snippet in your class ResumeTemplatePreviewBloc

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search