Vadym Silchenko
Vadym Silchenko

Reputation: 63

Flutter Undefined name 'context' for localization

Any help please how do I pass the context for localization here? error says: Undefined name 'context'. Try correcting the name to one that is defined, or defining the name.

category1.dart

import 'package:flutter/material.dart';
import 'package:myproject/classes/item.dart';
import 'page_details.dart';
import 'package:myproject/classes/language_constants.dart';

List<Item> detailsList = [
  Item(
      name: translation(context).name_1,
      image: 'assets/rivers/object1.jpg',
      details: translation(context).details_1,
      facts: [
        translation(context).fact_1_1,
        translation(context).fact_1_2,
        translation(context).fact_1_3,
      ],
    photolink: '',
    author: '',
    licensetype: '',
    licenselink: '',
  ),
  Item(
      name: translation(context).name_2,
      image: 'assets/rivers/object1.jpg',
      details: translation(context).details_2,
      facts: [
        translation(context).fact_2_1,
        translation(context).fact_2_2,
        translation(context).fact_2_3,
      ],
    photolink: '',
    author: '',
    licensetype: '',
    licenselink: '',
  ),
] 

tranlation() is defined as follows:

language_constants.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

AppLocalizations translation(BuildContext context) {
  return AppLocalizations.of(context)!;
}

Class Item is defined as follows:

item.dart

class Item {
  final String name;
  final String image;
  final String details;
  final String photolink;
  final String author;
  final String licensetype;
  final String licenselink;
  List<String> facts = <String>[];

  Item({
    required this.name,
    required this.image,
    required this.details,
    required this.facts,
    required this.photolink,
    required this.author,
    required this.licensetype,
    required this.licenselink,
  });
}

I pass appropriate class Item as a content via detailsList[index]:

category1.dart

ElevatedButton.icon(
          style: ElevatedButton.styleFrom(
            padding: const EdgeInsets.only(left: 8, right: 8),
            minimumSize: const Size(30, 30),
          ),
          onPressed: () {
            _navigateToPageDetails(context, detailsList[index]);
          },
...
)

and MaterialPageRoute():

category1.dart

_navigateToPageDetails(BuildContext context, Item item) async {
    await Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => PageDetails(
          item: item,
        ),
      ),
    );
  }

And finally the page:

page_details.dart

import 'package:myproject/classes/item.dart';

class PageDetails extends StatefulWidget {
  final Item item;

  const PageDetails({Key? key, required this.item}) : super(key: key);

  @override
  State<PageDetails> createState() => _PageDetailsState();
}

class _PageDetailsState extends State<PageDetails> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.item.name),
      ),
      body: SingleChildScrollView(
        child:Column(
          children: [
            Image.asset(widget.item.image),
            ...

So, I don't understand how to pass context to Class Item, so that this simple code doesn't throw the error:

translation(context).name_1,
-->
Error: Undefined name 'context'.

I've tried to add BuildContext context to the class, but it doesn't help. I've tried to use widget.context - the same, it doesn't help. Perhaps Class Item should extend some class? but experimenting with that also doesn't help.

Please help me..

Update after accepted answer

Following the perfect advice by Saichi Okuma above, I would like to share the code from my app, so that maybe it will be useful for somebody else.

Item detailsList(BuildContext context, index) {
  final List<Item> list = [];

  list.addAll([
    Item(
        name: translation(context).name_1,
        image: 'assets/rivers/object1.jpg',
        details: translation(context).details_1,
        facts: [
          translation(context).fact_1_1,
          translation(context).fact_1_2,
          translation(context).fact_1_3,
        ],
      photolink: '',
      author: '',
      licensetype: '',
      licenselink: '',
    ),
    Item(
        name: translation(context).name_2,
        image: 'assets/rivers/object2.jpg',
        details: translation(context).details_2,
        facts: [
          translation(context).fact_2_1,
          translation(context).fact_2_2,
          translation(context).fact_2_3,
        ],
      photolink: '',
      author: '',
      licensetype: '',
      licenselink: '',
    ),
  ]);
  
  final Item element = list[index];

  return element;
}

the function above gets the context and returns the required element of class Item.

and then instead of using a list (as in old initial code), I call the method as follows:

onPressed: () {
            _navigateToPageDetails(context, detailsList(context, index));
          }, 

Upvotes: 0

Views: 721

Answers (1)

Saichi Okuma
Saichi Okuma

Reputation: 254

There is no context present when you build your list, that's why you get the error. A simple way to solve, keeping your logic:


List<Item> detailsList(BuildContext context) {
  final List<Item> list = [];
  
  list.addAll([
    Item(
        name: translation(context).name_1,
        image: 'assets/rivers/object1.jpg',
        details: translation(context).details_1,
        facts: [
          translation(context).fact_1_1,
          translation(context).fact_1_2,
          translation(context).fact_1_3,
        ],
      photolink: '',
      author: '',
      licensetype: '',
      licenselink: '',
    ),
    Item(
        name: translation(context).name_2,
        image: 'assets/rivers/object1.jpg',
        details: translation(context).details_2,
        facts: [
          translation(context).fact_2_1,
          translation(context).fact_2_2,
          translation(context).fact_2_3,
        ],
      photolink: '',
      author: '',
      licensetype: '',
      licenselink: '',
    ),
  ]);
  
  return list;
} 

When you request a list, pass the context as argument.

Upvotes: 0

Related Questions