0

Ill try and provide as much code as possible. (mainly regarding the image ill be using "other data" instead of posting non needed code besides the image)

So in my app I have a File image; provider and im having issues with getting to display it on my app. Im unable to pass the File image path into firebase and its causing my app to crash when I try Fetching the data from firebase. Ill try providing as much code as possible.

Here is my provider:

import 'dart:io';

class AddCar {
 // other data
  File image;

  AddCar({
    // other data
    this.image,
  });
}

Here is my provider code:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:io';
import '../add_ons/add_car.dart';

List<AddCar> _cars = [];

class Cars with ChangeNotifier {
  List<AddCar> get cars {
    return [..._cars];
  }

  Future<void> fetchAndSetCars() async {
    const url = 'https://mycustomlink.firebaseio.com/cars.json';
    try {
      final response = await http.get(url);
      final extractedData = json.decode(response.body) as Map<String, dynamic>;
      var loadedCars = extractedData
          .map<String, AddCar>((carId, carData) => MapEntry(
              carId,
              AddCar(
                // other data
                image: File(carData['image']),
              )))
          .values
          .toList();
      _cars = loadedCars;
      print(extractedData);
      print(loadedCars);
      notifyListeners();
    } catch (error) {
      throw (error);
    }
  }

  AddCar findById(String id) {
    return _cars.firstWhere((carProd) => carProd.id == id);
  }

  void addCar(AddCar car) {
    const url = 'https://mycustomlink.firebaseio.com/cars.json';
    http.post(
      url,
      body: json.encode({
        // other data
        'image': car.image.toString(),
      }),
    );
    final newCar = AddCar(
      // other data
      image: car.image,
    );
    _cars.insert(0, newCar);

    notifyListeners();
  }
}

here is my form where the user enters data for it to be displayed:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_app/app_localization.dart';
import 'package:google_fonts_arabic/fonts.dart';
import 'package:provider/provider.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart' as syspaths;

import '../add_ons/add_car.dart';
import '../providers/car_provider.dart';

import '../drawer/drawer.dart';
import '../screens/cars_screen.dart';
import '../app_localization.dart';

class CreateCar extends StatefulWidget {
  static const routeName = '/create-car';

  @override
  _CreateCarState createState() => _CreateCarState();
}

class _CreateCarState extends State<CreateCar> {
  final _name = TextEditingController();
  final _price = TextEditingController();
  final _address = TextEditingController();

  String img;

  static Future<String> fileToB64(File f) async {
    List<int> imageBytes = f.readAsBytesSync();

    return base64Encode(
      imageBytes,
    );
  }

  Future<void> _takePicture() async {
    final imageFile = await ImagePicker.pickImage(
      source: ImageSource.gallery,
    );
    fileToB64(data.image).then((d) {
      setState(() {
        img = d; //base64Decode(d);
      });
    });
  }

  final _form = GlobalKey<FormState>();

  int currStep = 0;
  static AddCar data = new AddCar(
    id: null,
    date: DateTime.now(),
    sponsNum: '',
  );

  void _saveForm() {
    final isValid = _form.currentState.validate();
    if (!isValid) {
      return;
    }
    _form.currentState.save();
    Provider.of<Cars>(context, listen: false).addCar(data);
    Navigator.of(context).pushNamed(CarsScreen.routeName);
    print('this works');
  }

  @override
  Widget build(BuildContext context) {
    List<Step> steps = [
      Step(
        title: Text(
          AppLocalizations.of(context).createTabTitle,
        ),
        isActive: true,
        state: StepState.indexed,
        content: Column(
          children: <Widget>[
            // other data
          ],
        ),
      ),
      Step(
        title: Text(
          AppLocalizations.of(context).createCarDetails,
        ),
        isActive: true,
        state: StepState.indexed,
        content: Column(
          children: <Widget>[
            // other data
            Column(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(top: 25.0),
                  child: Container(
                    decoration: BoxDecoration(
                      border: Border.all(color: Theme.of(context).primaryColor),
                      borderRadius: BorderRadius.circular(50.0),
                    ),
                    child: FlatButton(
                      child: Text(AppLocalizations.of(context).createAddImages),
                      onPressed: _takePicture,
                    ),
                  ),
                )
              ],
            )
          ],
        ),
      ),
    ];

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text(
          AppLocalizations.of(context).createCarPageTitle,
          textAlign: TextAlign.center,
          style: TextStyle(
            fontFamily: ArabicFonts.Tajawal,
            package: 'google_fonts_arabic',
          ),
        ),
        actions: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              IconButton(
                icon: Icon(Icons.save),
                onPressed: _saveForm,
              ),
              IconButton(
                icon: Icon(Icons.arrow_forward),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              )
            ],
          ),
        ],
      ),
      drawer: MyDrawer(),
      body: Row(
        children: <Widget>[
          Form(
            key: _form,
            child: Expanded(
              child: Stepper(
                steps: steps,
                type: StepperType.vertical,
                currentStep: this.currStep,
                onStepContinue: () {
                  setState(() {
                    if (currStep < steps.length - 1) {
                      currStep = currStep + 1;
                    } else {
                      // currStep = 0;
                    }
                  });
                },
                onStepCancel: () {
                  setState(() {
                    if (this.currStep > 0) {
                      this.currStep = this.currStep - 1;
                    } else {
                      this.currStep = 0;
                    }
                  });
                },
                onStepTapped: (step) {
                  setState(() {
                    currStep = step;
                  });
                },
              ),
            ),
          ),
        ],
      ),
    );
  }
}

which is later passed into my "CarItem" that will display my code:

import 'package:flutter/material.dart';
import 'package:google_fonts_arabic/fonts.dart';
import '../icons/MyIcons.dart';
import 'dart:io';

import '../details/car_details.dart';
import '../app_localization.dart';

class CarItem extends StatelessWidget {
  final File image;

  CarItem(
   this.image,
  );

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border(
          bottom: BorderSide(color: Theme.of(context).primaryColor, width: 2.0),
        ),
      ),
      child: Column(
        children: <Widget>[
          Container(
            decoration: BoxDecoration(
              color: Color.fromARGB(255, 245, 245, 245),
            ),
            child: Padding(
              padding: const EdgeInsets.fromLTRB(17.0, 4.0, 17.0, 4.0),
              child: Row(
                textDirection: TextDirection.rtl,
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  // other data
                ],
              ),
            ),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Container(
                width: MediaQuery.of(context).size.width * 0.35,
                height: MediaQuery.of(context).size.width * 0.35,
                child: GestureDetector(
                  child: Image.file(
                    image,
                    fit: BoxFit.fill,
                  ),
                  onTap: () {
                    Navigator.of(context).pushNamed(
                      MyCarDetails.routeName,
                      arguments: id,
                    );
                  },
                ),
              ),
              Container(
                width: MediaQuery.of(context).size.width * 0.65,
                margin: EdgeInsets.all(0),
                padding: const EdgeInsets.fromLTRB(22.0, 5.0, 22.0, 0),
                child: Column(
                  children: <Widget>[
                    // other data
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

this code gets called by a list that will call the code and display it in my app:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:google_fonts_arabic/fonts.dart';

import '../providers/car_provider.dart';
import '../widget/car_item.dart';

class CarsList extends StatefulWidget {
  @override
  _CarsListState createState() => _CarsListState();
}

class _CarsListState extends State<CarsList> {
  @override
  Widget build(BuildContext context) {
    final carsData = Provider.of<Cars>(context);
    final car = carsData.cars;
    return car.isEmpty
        ? Center(
            child: Text(
            'no data yet available',
            style: TextStyle(
              fontFamily: ArabicFonts.Tajawal,
              fontWeight: FontWeight.bold,
              package: 'google_fonts_arabic',
            ),
          ))
        : ListView.builder(
            padding: const EdgeInsets.only(bottom: 47.0),
            itemCount: car.length,
            itemBuilder: (ctx, i) => CarItem(
              // other data
              car[i].image,
            ),
          );
  }
}

this is the error i keep getting when It tries to display fetched data:

════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building CarItem(dirty, dependencies: [_LocalizationsScope-[GlobalKey#31697], MediaQuery, _InheritedTheme]):
The method '+' was called on null.
Receiver: null
Tried calling: +("25")

User-created ancestor of the error-causing widget was
    ListView 
lib\home_parts\cars_area.dart:49
When the exception was thrown, this was the stack
#0      Object.noSuchMethod  (dart:core-patch/object_patch.dart:51:5)
#1      CarItem.build 
package:flutter_app/widget/car_item.dart:151
#2      StatelessElement.build 
package:flutter/…/widgets/framework.dart:4009
#3      ComponentElement.performRebuild 
package:flutter/…/widgets/framework.dart:3941
#4      Element.rebuild 
package:flutter/…/widgets/framework.dart:3738
...
════════════════════════════════════════════════════════════════════════════════

How can I fix this? is the issue in how im passing the data to firebase and displaying it on my app?

  • Could you post the error you're getting? – Pablo Barrera Oct 30 '19 at 09:38
  • @PabloBarrera just added it at the bottom its strange because I think since it cant display an image its trying to take the value in my "Price" `textformfield` –  Oct 30 '19 at 10:27
  • You posted all the code of CarItem? It seems that inside the build() method of CarItem somewhere you're using "+" and I don't see any "+" in the code you posted. – Pablo Barrera Oct 30 '19 at 10:41
  • This error doesn't refer to image.As the error messages says ``The method '+' was called on null.`` just look into your CaItem where you are using ``+`` operator left-hand value is null – Constantin N. Oct 30 '19 at 10:47
  • its my price code which i didnt include because i just wanted to keep the code short relating to the image but here is the price code display which is giving an error ` Text(currencyT + price,style: TextStyle(color:Theme.of(context).accentColor, fontWeight: FontWeight.bold,),),` –  Oct 30 '19 at 10:48
  • Is that this line? car_item.dart:151 if so, then currencyT is null. Where does this value come from? – Richard Heap Oct 31 '19 at 11:01
  • yes it is. the currencyT is a dropdown item with 2 values which are currencies one for Dollar and one for Euro –  Oct 31 '19 at 13:23

0 Answers0