Debug School

rakesh kumar
rakesh kumar

Posted on

How to renders data in Flutter Using MVMM architecture

Step1:create a modal

import 'dart:convert';

class SearchInfluencer {
  int id;
  String? userId;
  String? userName;
  String? userEmail;
  String? filePic;
  String? slugId;
  String? slug;
  String? slugname;
  String? countryId;
  String? stateId;
  String? cityId;
  String? mobile;
  String? digitalMarketer;
  String? bio;
  String? socialSite;
  String? socialPrice;
  String? socialCurrency;
  String? adminId;
  String? cartId;
  String? influencerAdminId;
  String? cartSocials;
  String? currency;
  String? influencerEmail;

  SearchInfluencer({
    this.id = 0,
    this.userId,
    this.userName,
    this.userEmail,
    this.filePic,
    this.slugId,
    this.slug,
    this.slugname,
    this.countryId,
    this.stateId,
    this.cityId,
    this.mobile,
    this.digitalMarketer,
    this.bio,
    this.socialSite,
    this.socialPrice,
    this.socialCurrency,
    this.adminId,
    this.cartId,
    this.influencerAdminId,
    this.cartSocials,
    this.currency,
    this.influencerEmail,
  });

  factory SearchInfluencer.fromJson(Map<String, dynamic> map) {
    return SearchInfluencer(
      id: map["id"] ?? 0,
      userId: map["user_id"],
      userName: map["user_name"],
      userEmail: map["user_email"],
      filePic: map["file_pic"],
      slugId: map["slug_id"],
      slug: map["slug"],
      slugname: map["slugname"],
      countryId: map["country_id"],
      stateId: map["state_id"],
      cityId: map["city_id"],
      mobile: map["mobile"],
      digitalMarketer: map["digital_marketer"],
      bio: map["bio"],
      socialSite: map["social_site"],
      socialPrice: map["social_price"],
      socialCurrency: map["social_currency"],
      adminId: map["admin_id"],
      cartId: map["cart_id"],
      influencerAdminId: map["influencer_admin_id"],
      cartSocials: map["cart_socials"],
      currency: map["currency"],
      influencerEmail: map["influencer_email"],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      "id": id,
      "user_id": userId,
      "user_name": userName,
      "user_email": userEmail,
      "file_pic": filePic,
      "slug_id": slugId,
      "slug": slug,
      "slugname": slugname,
      "country_id": countryId,
      "state_id": stateId,
      "city_id": cityId,
      "mobile": mobile,
      "digital_marketer": digitalMarketer,
      "bio": bio,
      "social_site": socialSite,
      "social_price": socialPrice,
      "social_currency": socialCurrency,
      "admin_id": adminId,
      "cart_id": cartId,
      "influencer_admin_id": influencerAdminId,
      "cart_socials": cartSocials,
      "currency": currency,
      "influencer_email": influencerEmail,
    };
  }

  @override
  String toString() {
    return 'SearchInfluencer{id: $id, userId: $userId, userName: $userName, userEmail: $userEmail, filePic: $filePic, slugId: $slugId, slug: $slug, slugname: $slugname, countryId: $countryId, stateId: $stateId, cityId: $cityId, mobile: $mobile, digitalMarketer: $digitalMarketer, bio: $bio, socialSite: $socialSite, socialPrice: $socialPrice, socialCurrency: $socialCurrency, adminId: $adminId, cartId: $cartId, influencerAdminId: $influencerAdminId, cartSocials: $cartSocials, currency: $currency, influencerEmail: $influencerEmail}';
  }

  bool startsWith(String query) {
    return userName?.toLowerCase().contains(query.toLowerCase()) ?? false;
  }
}

List<SearchInfluencer> searchInfluencerFromJson(String jsonData) {
  final data = json.decode(jsonData);
  return List<SearchInfluencer>.from(data.map((item) => SearchInfluencer.fromJson(item)));
}

String searchInfluencerToJson(SearchInfluencer data) {
  final jsonData = data.toJson();
  return json.encode(jsonData);
}
Enter fullscreen mode Exit fullscreen mode

Step2: To call api define method

import 'dart:convert';
import 'package:flutter_application_1/model/search_influencer.dart';
import 'package:http/http.dart' as http;


class InfluencerAPI {
  String baseUrl = "https://www.wizbrand.com/";

  Future<List<SearchInfluencer>> getinfluencer() async {
    var url = "$baseUrl/api/getinfluencer/";
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      List<dynamic> body = jsonDecode(response.body);
      return body.map((user) => SearchInfluencer.fromJson(user)).toList();
    } else {
      throw Exception("failed to upload influencer data");
    }
  }

}
Enter fullscreen mode Exit fullscreen mode

step3: Creates a ViewModel for manages the state of influencer data fetching and notifies listeners (usually UI components) about changes in the state

.

import 'package:flutter_application_1/model/search_influencer.dart';
import 'package:flutter/material.dart';
import 'package:flutter_application_1/Service/Influencer/influencer_service.dart';


class InfluencerViewModel extends ChangeNotifier {
  final InfluencerAPI api;
  List<SearchInfluencer> influencers = [];
  bool isLoading = false;

  InfluencerViewModel(this.api);

  Future<void> fetchInfluencers() async {
    isLoading = true;
    notifyListeners();

    try {
      influencers = await api.getinfluencer();
       print("Data fetched successfully: ${influencers.length} items");
    } catch (e) {
      print(e);
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation
Importing Necessary Packages:

import'package:flutter_application_1/model/search_influencer.dart'import 'package:flutter/material.dart';
import 'package:flutter_application_1/Service/Influencer/influencer_service.dart';
Enter fullscreen mode Exit fullscreen mode

Image description

Defining the InfluencerViewModel Class:

class InfluencerViewModel extends ChangeNotifier {
  final InfluencerAPI api;
  List<SearchInfluencer> influencers = [];
  bool isLoading = false;

  InfluencerViewModel(this.api);
Enter fullscreen mode Exit fullscreen mode

Image description

Defining the fetchInfluencers Method:

  Future<void> fetchInfluencers() async {
    isLoading = true;
    notifyListeners();

    try {
      influencers = await api.getinfluencer();
      print("Data fetched successfully: ${influencers.length} items");
    } catch (e) {
      print(e);
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Image description

Check for Null Values:
Ensure your data model handles nullable fields correctly, as shown in the updated model. This will prevent runtime errors due to unexpected null values.

Use Debugger:
Use the Flutter debugger to set breakpoints and inspect the state of your application at runtime.

step4:Renders data in screen

import 'package:flutter/material.dart';
import 'package:flutter_application_1/Screen/Influencer/Influencerscreen.dart';
import 'package:flutter_application_1/Service/Influencer/influencer_service.dart';
import 'package:flutter_application_1/view_modal/influencer_view_model.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => InfluencerViewModel(InfluencerAPI()),
        ),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
   return const MaterialApp(
      title: 'Influencer App',
      home: Influencerscreen(),
    );

  }
}
Enter fullscreen mode Exit fullscreen mode

influencerscreen

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_application_1/view_modal/influencer_view_model.dart';

class Influencerscreen extends StatefulWidget {
  const Influencerscreen({super.key});
  @override
  State<Influencerscreen> createState() => _InfluencerscreenState();
}

class _InfluencerscreenState extends State<Influencerscreen> {
  @override
  void initState() {
  super.initState();   
  Future.microtask(() =>
        Provider.of<InfluencerViewModel>(context, listen: false).fetchInfluencers());
  }  
  @override
  Widget build(BuildContext context) {
    final viewModel = Provider.of<InfluencerViewModel>(context);
    return Scaffold(
      appBar: AppBar(
        title: const Text('Influencers'),
      ),
      body: viewModel.isLoading
          ? const Center(child: CircularProgressIndicator())
          : viewModel.influencers.isEmpty
              ? const Center(child: Text('No influencers found'))
              : ListView.builder(
                  itemCount: viewModel.influencers.length,
                  itemBuilder: (context, index) {
                    final influencer = viewModel.influencers[index];
                    return ListTile(
                      title: Text(influencer.userName ?? "No Name"), // Adjust based on your model
                      subtitle: Text(influencer.slug ?? "No Details"), // Adjust based on your model
                    );
                  },
       ),
        floatingActionButton: FloatingActionButton(
        onPressed: () => viewModel.fetchInfluencers(),
        child: const Icon(Icons.refresh),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation

Step-by-Step Explanation
Import Necessary Packages:
Ensure you have imported all necessary packages.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_application_1/view_modal/influencer_view_model.dart';
Enter fullscreen mode Exit fullscreen mode

Define the Stateful Widget:
Define your Influencerscreen widget which extends StatefulWidget.

class Influencerscreen extends StatefulWidget {
  const Influencerscreen({super.key});

  @override
  State<Influencerscreen> createState() => _InfluencerscreenState();
}
Enter fullscreen mode Exit fullscreen mode

State Class Initialization:
Inside the _InfluencerscreenState class, override the initState method. This is where you initialize fetching of influencers data using the InfluencerViewModel.

class _InfluencerscreenState extends State<Influencerscreen> {
  @override
  void initState() {
    super.initState();
    // Fetch influencers when the screen is first created
    Future.microtask(() =>
        Provider.of<InfluencerViewModel>(context, listen: false).fetchInfluencers());
  }
Enter fullscreen mode Exit fullscreen mode

Here, Future.microtask is used to ensure that the fetchInfluencers method is called as soon as the widget is created.

Building the UI:
Override the build method to define the UI of your screen.

@override
Widget build(BuildContext context) {
  final viewModel = Provider.of<InfluencerViewModel>(context);
Enter fullscreen mode Exit fullscreen mode

Use Provider.of(context) to access the view model instance. This allows the UI to reactively rebuild when the view model's state changes.

Scaffold and AppBar:
Create a Scaffold widget to provide the structure of the screen, including an AppBar.

return Scaffold(
  appBar: AppBar(
    title: const Text('Influencers'),
  ),
Enter fullscreen mode Exit fullscreen mode

Conditional Body Content:
Depending on the state of isLoading and the list of influencers, display different widgets.

body: viewModel.isLoading
    ? const Center(child: CircularProgressIndicator())
    : viewModel.influencers.isEmpty
        ? const Center(child: Text('No influencers found'))
        : ListView.builder(
            itemCount: viewModel.influencers.length,
            itemBuilder: (context, index) {
              final influencer = viewModel.influencers[index];
              return ListTile(
                title: Text(influencer.userName ?? "No Name"), // Adjust based on your model
                subtitle: Text(influencer.slug ?? "No Details"), // Adjust based on your model
              );
            },
          ),
Enter fullscreen mode Exit fullscreen mode
  • If isLoading is true, display a CircularProgressIndicator.
  • If the influencers list is empty, display a message "No influencers found".
  • If there are influencers, use a ListView.builder to display them.
  • Floating Action Button:
  • Add a FloatingActionButton to allow manual refreshing of the influencer list .
floatingActionButton: FloatingActionButton(
  onPressed: () => viewModel.fetchInfluencers(),
  child: const Icon(Icons.refresh),
),
Enter fullscreen mode Exit fullscreen mode

This button triggers the fetchInfluencers method when pressed.

Top comments (0)