skip to Main Content

I wanted to make connection with my WordPress with API, I successfully made the connection and fetched JSON, here is the connection code

// ignore_for_file: avoid_print

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:testapi/courses.dart';

Future fetchCourses() async {
  String username = "walid.beday";
  String password = "wordpress application password";
  String credentials = "Basic ${base64.encode(
    utf8.encode("$username:$password"),
  )}";
  print(credentials);
  final response = await http.get(
    Uri.parse("https://example.com/wp-json/wp/v2/sfwd-courses"),
    headers: {"authorization": credentials},
  );
  final responseJson = jsonDecode(response.body);
  if (response.statusCode == 200) {
    for (var course in responseJson) {
      print(course["title"]["rendered"]);
      );
    }
    print("Good connetiopn".toUpperCase());
  } else {
    ("bad connection".toUpperCase());
  }
}

and this is class Course

// ignore_for_file: public_member_api_docs, sort_constructors_first
class Courses {
  String courseTitle;
  int courseId;
  Courses({
    required this.courseTitle,
    required this.courseId,
  });
}

I dont know how to take the value from json and add them to course class and return this class in listview builder, here is main.dart

import 'package:flutter/material.dart';
import 'package:testapi/courses.dart';
import 'config.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

var courses = [];

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.red),
        useMaterial3: true,
      ),
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).appBarTheme.backgroundColor,
          elevation: 20,
          title: const Text("Test Api"),
        ),
        floatingActionButton: const FloatingActionButton(
          onPressed: fetchCourses,
        ),
        body: ListView.builder(
          itemCount: ,
          itemBuilder: (BuildContext context, int index) {
            return Courses(courseTitle: courseTitle, courseId: courseId);
          },
        ),
      ),
    );
  }
}


I dont know what how to ListView.builder to fetch courses

I tried this but didnt work

// ignore_for_file: avoid_print

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:testapi/courses.dart';

Future fetchCourses() async {
  String username = "walid.beday";
  String password = "wordpress application password";
  String credentials = "Basic ${base64.encode(
    utf8.encode("$username:$password"),
  )}";
  print(credentials);
  final response = await http.get(
    Uri.parse("https://example.com/wp-json/wp/v2/sfwd-courses"),
    headers: {"authorization": credentials},
  );
  final responseJson = jsonDecode(response.body);
  if (response.statusCode == 200) {
    for (var course in responseJson) {
      print(course["title"]);
      return Courses(
        courseId: responseJson["id"],
        courseTitle: responseJson["title"]["rendered"],
      );
    }

    print("Good connetiopn".toUpperCase());
  } else {
    ("bad connection".toUpperCase());
  }
}

2

Answers


  1. Chosen as BEST ANSWER

    I get an error in app

    When I print(responseJson)

    i get this json

    8
    I/flutter ( 4594): [{id: 12173, date: 2023-06-14T21:48:08, date_gmt: 2023-06-14T18:48:08, guid: {rendered: https://example.com/courses/est-2-ossama-mohamed-2/}, modified: 2023-06-17T16:32:19, modified_gmt: 2023-06-17T13:32:19, slug: g10, status: publish, type: sfwd-courses, link: https://example.com/courses/g10/, title: {rendered: G10 By Mr. Ossama}, content: {rendered: , protected: false}, author: 310, featured_media: 7228, menu_order: 0, template: , meta: [], ld_course_category: [132, 129], acf: [], course_materials: , course_price_type: closed, custom_button_label: , custom_button_url: , course_price: , course_prerequisite_enabled: , course_prerequisite: , course_prerequisite_compare: ANY, course_points_enabled: , course_points: , course_points_access: , course_disable_lesson_progression: on, expire_access: , expire_access_days: 0, expire_access_delete_progress: , _links: {self: [{href: https://example.com/wp-json/wp/v2/sfwd-courses/12173}], collection: [{href: https://example.com/wp-json/wp/v2/s
    

  2. You probably want to do something like this…

    First, create a constructor factory on your class (note that I had to make some assumptions about the data when I was casting the json variable):

    class Courses {
      String courseTitle;
      int courseId;
      Courses({
        required this.courseTitle,
        required this.courseId,
      });
    
      factory Courses.fromJson(Map<String, dynamic> json) {
            return Courses(
              courseTitle: (json['title'] as Map<String, String>)["rendered"] ?? 'Unknown',
              courseId: int.parse((json['id']) as String? ?? '0'),
            );
        }
    }
    

    Then, change your return type to be a Future<List<Courses>>, create an empty list, and populate it with each item you build (note that I did not check your method for accuracy or other issues – I just created the list, cast the results into new Courses classes, added them to the list, and returned the list):

    Future<List<Courses>> fetchCourses() async {
      const String username = "walid.beday";
      const String password = "wordpress application password";
      final String credentials = "Basic ${base64.encode(
        utf8.encode("$username:$password"),
      )}";
      print(credentials);
      final response = await http.get(
        Uri.parse("https://example.com/wp-json/wp/v2/sfwd-courses"),
        headers: {"authorization": credentials},
      );
      final List<Courses> courses = [];
      final responseJson = jsonDecode(response.body);
      if (response.statusCode == 200) {
        for (final Map<String, dynamic> course in responseJson) {
          final Courses newCourse = Courses.fromJson(course);
          courses.add(newCourse);
        }
        print("Good connetiopn".toUpperCase());
      } else {
        "bad connection".toUpperCase();
      }
    
      return courses;
    }
    

    Next, you need to properly invoke your method using a FutureBuilder and doing some basic state handling:

    body: FutureBuilder(
      future: fetchCourses(),
      builder: (context, AsyncSnapshot<List<Courses>> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const CircularProgressIndicator();
        }
        if (snapshot.connectionState == ConnectionState.done &&
            (!snapshot.hasData || snapshot.hasError)) {
          return const Text('Error');
        }
    
        final List<Courses> courses = snapshot.data!;
        return ListView.builder(
          itemCount: courses.length,
          itemBuilder: (BuildContext context, int index) {
            return ListTile(
              title: Text(courses[index].courseTitle),
            );
          },
        );
      },
    ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search