I'm creating a Flutter application. I'm added a BloC to my project for management state.
I created a list with data. And I want to add item to ListView manually with button 'Add'.
I'm wrote a code:
My Item Cubit
class ItemCubit extends Cubit<List<Item>> {
ItemCubit() : super([]);
void addItem(item){
state.add(item);
emit(state);
}
}
Page of Items with Provider:
class SearchPage extends StatelessWidget {
const SearchPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider(
create: (_) => ItemCubit(),
child: Search(),
),
);
}
}
And I call the BlocBuilder in Stateless Widget like this:
body: BlocBuilder<MarketCubit, List<Market>>(
builder: (context, items) => TabBarView(...))
So when I call my function from state:
Item item = Item(1, 'Item 1');
ElevatedButton(onPressed:(){
context.read<ItemCubit>().addItem(item);
}, child: Text('Add Item')),
The ListView doesn't updating. What's problem?
Thanks a lot!
The problem is that you are just adding the item to the state and re-emitting the same (modified) list. Bloc will essentially check the value of the state object to see if it is a new object when you call emit(), if it is the 'same list' as the last state, it will do nothing. It is confusing because even though you are adding a new value to the list, it is still the same object in a sense, just with a new value.
So there should be an easy fix if you just create a new list instead of modifying the original one and emit that.
For example, this should fix the issue:
emit([...state, newValue])
or
final newList = List.from(state)..add(newValue);
emit(newList);
(I had trouble finding in the bloc documentation where this is explained, but there are a number of issue threads where it is discussed -https://github.com/felangel/bloc/issues/2374)
Essentially, the state should be 'immutable', so if you are going to emit a new state, you should actually create a new instance of whatever you are going to emit. The way I typically use the state is to have a class with final fields for whatever state the cubit is tracking, and a copyWith method that makes it easy to create a new instance with any modified fields:
YourCubitState{
final List stateList;
final otherField;
const YourCubitState({
this.stateList = [],
this.otherField,
});
YourCubitState copyWith({
List? stateList,
otherField,
}) =>
YourCubitState(
stateList: stateList ?? this.stateList,
otherField: otherField ?? this.otherField,
);
}
Maybe that is unnecessary if the state is just a single list, but if you find yourself wanting to add properties to the state, that is a good pattern to follow.
create new variable, add them to the new variable list, update your new variable list item to it, emit the data with the new variable. this is how i got it working.
late List<ServicesExpensesList> newList = <ServicesExpensesList>[];
state.utilityDataList.forEach((element) {
newList.add(element);
});
newList.insert(0, utilityData);
newList.sort((a, b) => b.createdAt.compareTo(a.createdAt));
emit(state.copyWith(
utilityDataList: newList,
status: state.status == BlocStateStatus.success
? BlocStateStatus.updated
: BlocStateStatus.success,
))
ItemCubit class superclass not holding your state. You should manage yourself states. So, what I say, I'm saying create list variable inside ItemCubit class and every call addItem method add item to this list and emit this list.
Your Cubit class should be as below;
abstract class ItemState {
const ItemState();
}
class ItemInitial extends ItemState {
const ItemInitial();
}
class ItemStateUpdatedList extends ItemState {
const ItemStateUpdatedList({required this.list});
final List<Item> list;
}
class ItemCubit extends Cubit<ItemState> {
ItemCubit() : super(const ItemInitial());
final List<Item> myItemList = [];
void addItem(item){
myItemList.add(item);
emit(ItemStateUpdatedList(list: myItemList));
}
}
body: BlocBuilder<ItemCubit, ItemState>(
builder:(context, state) {
if(state is ItemStateUpdatedList){
final list = state.list;
return TabBarView(...);
}
return const SizedBox.shrink();
},
)
Cubit or block is a state change emitter, and since state is a set of attributes and properties then, the key thing here is the ability of Cubit and Bloc to figure out that something has been changed with properties or attributes otherwise will not emit new state.
this is how it works for me:
abstract class ObjectListState extends Equatable {
`final List<String> items;
const ObjectListState(this.items);
}
class ObjectListStateInitial extends ObjectListState {
const ObjectListStateInitail(super.items);
#override
List<Object> get props => [];
}
class ObjectListStateItemAdded extends ObjectListState {
final String item;
final List<String> items;
ObjectListStateItemAdded( this.item, this.items) : super(items){
items.add(item);
}
#override
List<Object> get props => [item,items];
}
Related
Possible solution if there is any ?
I lave a list of tabar like:
final tabList = [
Icons.camera,
"CHATS",
"STATUS",
"CALLS",
];
and i want to use this list like this way:
TabBar(
tabs: tabList.map((e) => Tab()).toList();
and i want to set the value for icon and rest of them for text.
You can't create a list with two data types. Either you can create a list of type String or of type IconData. Optionally if you want both the properties together in a list you might try creating a class for accommodating the two types.
import 'package:flutter/material.dart';
class TabItem {
TabItem(this.name, this.icon);
String name;
IconData icon;
}
final tabList = [
TabItem("Camera", Icons.camera),
TabItem("Calls", Icons.phone),
TabItem("Status", Icons.signal_wifi_statusbar_4_bar),
];
_getTabs() {
return tabList.map((e) {
return Tab(
text: e.name,
child: Icon(e.icon),
);
});
}
You can have tabList of type List<dynamic>, but that may cause issues.
Another solution would be to create an abstract class with child classes:
abstract class TabItem {}
class IconTab extends TabItem {
final IconData icon;
IconTab(this.icon);
}
class TitleTab extends TabItem {
final String title;
TitleTab(this.title);
}
and then set tabList of type List<TabItem>
final List<TabItem> tabList = [
IconTab(Icons.camera),
TitleTab("CHATS"),
TitleTab("STATUS"),
TitleTab("CALLS"),
];
how i must write this code in bloc v.8 i don know how i see some searches but im not understand and this is my code for classes they give me error => StateError (Bad state: add(DoFetchEvent) was called without a registered event handler.
Make sure to register a handler via on((event, emit) {...})):
class PostBloc extends Bloc<PostEvent, PostState> {
PostRepository repo;
PostBloc(PostState initialState, this.repo) : super(initialState);
Stream<PostState> mapEventToState(PostEvent event) async* {
if (event is DoFetchEvent) {
yield LoadingState();
try {
var posts = await repo.fetchPosts();
yield FetchSuccess(posts: posts);
} catch (e) {
yield ErrorState(message: e.toString());
}
}
}
}
import 'package:equatable/equatable.dart';
class PostEvent extends Equatable {
#override
List<Object?> get props => [];
}
class DoFetchEvent extends PostEvent {}
class PostState extends Equatable {
#override
List<Object?> get props => [];
}
class InitialState extends PostState {}
class LoadingState extends PostState {}
class FetchSuccess extends PostState {
List<PostModel> posts;
FetchSuccess({required this.posts});
}
class ErrorState extends PostState {
String message;
ErrorState({required this.message});
}
void main() {
runApp(MaterialApp(
home: BlocProvider(
create: (context) => PostBloc(InitialState(), PostRepository()),
child: MyApp(),
),
));
}
You can set your InitialState directly in the super constructor without manually passing it in like so.
PostBloc(this.repo) : super(InitialState()) {
on<DoFetchEvent>(_onDoFetchEvent);
}
Then you no longer pass in any state in the BlocProvider
BlocProvider<PostBloc>(
create: (BuildContext context) => PostBloc(PostRepository()),
...
Then your mapEventToState gets replaced with a method that takes the relevant event, and an Emitter<PostState> as arguments. yield then gets replaced with emit in the method.
Your whole class would look like this.
PostBloc(this.repo) : super(InitialState()) {
on<DoFetchEvent>(_onDoFetchEvent);
}
_onDoFetchEvent(
DoFetchEvent event,
Emitter<PostState> emit,
) async {
emit(LoadingState());
try {
var posts = await repo.fetchPosts();
emit(FetchSuccess(posts: posts));
} catch (e) {
emit(ErrorState(message: e.toString()));
}
}
}
That should do it.
Besides that, you're probably getting linter warnings about must_be_immutable on your state classes because PostState extend Equatable.
So I suggest making all PostState parameters final and adding the props override from Equatable to your state classes.
class ErrorState extends PostState {
final String message;
ErrorState({required this.message});
#override
List<Object?> get props => [message];
}
I am trying to fetch data from a local json file in my assets. I received and decoded data and then tried to store it in a list for further use. But it give me the exception. I want the list to be of type OriginDestination, store it in database and then use it further. Can someone please tell me how can I parse data from json to OriginDestination.
Class OriginDestination -
OriginDestination cityDtoFromJson(String str) => OriginDestination.fromJson(json.decode(str));
String cityDtoToJson(OriginDestination data) => json.encode(data.toJson());
#HiveType(typeId: 0)
// ignore: non_constant_identifier_names
class OriginDestination extends HiveObject {
#HiveField(0)
City? origin;
#HiveField(1)
List<City>? destinations;
OriginDestination({
this.origin,
this.destinations,
});
factory OriginDestination.fromJson(Map<String, dynamic> json) => OriginDestination(
origin: City.fromJson(json["origin"]),
destinations: List<City>.from(
json["destinations"].map((x) => City.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"origin": origin,
"destinations": destinations,
};
Code where I am fetching data and want to use it (originDestinations is also a list of type OriginDestination) -
List<OriginDestination>? localOriginDestination = [];
Future<void> readJson() async {
final String response = await rootBundle.loadString('assets/files/node.json');
final data = await json.decode(response);
localOriginDestination = await data["data"].cast<OriginDestination>();
print(localOriginDestination);
if(localOriginDestination!=null) {
await _localStorageService.getBox().clear();
await _localStorageService.getBox().addAll(localOriginDestination!.toList());
originDestinations = _localStorageService.getOriginDestinations();
}
}
I have never used Hive before but this line of code seems suspicious to me:
localOriginDestination = await data["data"].cast<OriginDestination>();
I think you want to do something along the lines of:
localOriginDestination = [
for (final element in await data['data']) OriginDestination.fromJson(element),
];
But I can't be entirely certain without knowing what the value of await data['data'] is.
Edit, adding some more information.
The .cast method on List is only meant to be used with a type that is a subtype of the original list type, like in this example:
void main() {
List<num> nums = [1, 2, 3];
List<int> ints = nums.cast<int>();
ints.add(4);
print(ints);
}
What you are doing is essentially the same thing as this.
void main() {
List<Map<String, int>> items = [
{'A': 1, 'B': 2},
{'A': 3, 'B': 4},
];
final result = items.cast<ABC>();
print(result);
}
class ABC {
int a;
int b;
ABC.fromJson(Map<String, dynamic> json)
: a = json['A'],
b = json['B'];
}
The problem here is that the ABC class is not a subtype of Map<String, int>. Classes are not maps in the dart programming language. You need to need to call the .fromJson constructor on each element of the items list in order to get a List<ABC>.
You can do it in a few different ways.
Using map method is one approach. (you need to be on dart 2.15+ for this exact syntax)
List<ABC> result = items.map(ABC.fromJson).toList();
Looping over items with a collection for is another approach.
List<ABC> result = [for (final element in items) ABC.fromJson(element)];
Looping over items with a conventional for loop is yet another approach.
List<ABC> result = [];
for (final element in items) {
result.add(ABC.fromJson(element));
}
In flutter string text are directly set to the TextField widget like:
new Text('Hello, How are you?')
Is correct way ? or we can maintain all string in one file and use it like:
<string name="name_hint">Hello, How are you?</string>
Is it possible ?
Flutter currently doesn’t have a dedicated resources-like system for strings. At the moment, the best practice is to hold your copy text in a class as static fields and accessing them from there. For example:
class Strings {
static const String welcomeMessage = "Welcome To Flutter";
}
Then in your code, you can access your strings as such:
Text(Strings.welcomeMessage)
source
Edit May '19:
There's now this package that allows you to create json files with your Strings. It will allow you to create Strings for plurals, genders and languages etc
You can create a separate json file for each language like so:
string_en.json
{
"thanks": "Thanks."
}
string_nl.json
{
"thanks": "Dankjewel."
}
And then use this to access it
S.of(context).thanks;
It will know which language to choose based on your phone's default language.
Screenshot:
Full Code (Null safe):
For those of you who don't want to use any 3rd party plugin, here is how you can do it.
Create a folder strings in assets. Put your language file in it.
assets
strings
- en.json // for english
- ru.json // for russian
Now in en.json, write your string, for example.
{
"text1": "Hello",
"text2": "World"
}
Similarly, in ru.json,
{
"text1": "Привет",
"text2": "Мир"
}
Add this to pubspec.yaml file (mind the spaces)
flutter:
uses-material-design: true
assets:
- assets/strings/en.json
- assets/strings/ru.json
flutter_localizations:
sdk: flutter
Now you are all set to use these strings in your app. Here is the sample code, the AppBar shows the translated text.
void main() {
runApp(
MaterialApp(
locale: Locale("ru"), // switch between en and ru to see effect
localizationsDelegates: [const DemoLocalizationsDelegate()],
supportedLocales: [const Locale('en', ''), const Locale('ru', '')],
home: HomePage(),
),
);
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(DemoLocalizations.of(context).getText("text2") ?? "Error")),
);
}
}
// this class is used for localizations
class DemoLocalizations {
static DemoLocalizations? of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
}
String getText(String key) => language[key];
}
late Map<String, dynamic> language;
class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
const DemoLocalizationsDelegate();
#override
bool isSupported(Locale locale) => ['en', 'ru'].contains(locale.languageCode);
#override
Future<DemoLocalizations> load(Locale locale) async {
String string = await rootBundle.loadString("assets/strings/${locale.languageCode}.json");
language = json.decode(string);
return SynchronousFuture<DemoLocalizations>(DemoLocalizations());
}
#override
bool shouldReload(DemoLocalizationsDelegate old) => false;
}
You can use the methods represented in the internationalization sections of the documentation to control both centralized string management and translations (if you need translations)
https://flutter.io/tutorials/internationalization/
It might be overkill for a simple app with only a few strings though.
I would separate these classes into individual files, but just to explain my approach for this question.
I have a base class which has my strings getters. Every language I want to support I have to create a class which extends from this class and override its getters. Thus, whenever I create a string, I have to override each implementation of this base class. It is helpful to avoid forgetting to create some locale specific string.
/// Interface strings
class Strings {
String get hello;
}
/// English strings
class EnglishStrings extends Strings {
#override
String get hello => 'Hello';
}
/// Russian strings
class RussianStrings extends Strings {
#override
String get hello => 'Привет';
}
/// Portuguese strings
class PortugueseStrings extends Strings {
#override
String get hello => 'Olá';
}
After that, in a global scope of your application, you could declare a unique instance of the locale you want to use (using a singleton is a good option).
Just showing a short example of using it:
class Resources {
BuildContext _context;
Resources(this._context);
Strings get strings {
// It could be from the user preferences or even from the current locale
Locale locale = Localizations.localeOf(_context);
switch (locale.languageCode) {
case 'pt':
return PortugueseStrings();
case 'ru':
return RussianStrings();
default:
return EnglishStrings();
}
}
static Resources of(BuildContext context){
return Resources(context);
}
}
And finally, using it in some widget:
Text(Resources.of(context).strings.hello)
Using an extension from BuildContext
You can extend BuildContext to create some particular features and give more power to your application.
This is available from Dart 2.7. See more.
app_context_extension.dart
extension AppContext on BuildContext {
Resources get resources => Resources.from(this);
}
favorites_page.dart
import 'package:flutter/material.dart';
// you have to import it yourself. The auto import does not work in this case
import 'package:myapp/ui/extensions/app_context_extension.dart';
class FavoritesPage extends StatefulWidget {
#override
_FavoritesPageState createState() => _FavoritesPageState();
}
class _FavoritesPageState extends State<FavoritesPage> {
#override
Widget build(BuildContext context) {
return Text(context.resources.strings.hello);
}
}
Using GlobalKey
Along with an extension of BuildContext as shown above, you can also use GlobalKey.
Basically, you could use it when you do not have a context instance.
This last one has a good advantage. You could use strings anywhere in your application. In other words, if you use some pattern like MVC for instance and want to use strings in your controllers, you could easily do it.
You can declare something like this:
application.dart
import 'package:myapp/ui/extensions/app_context_extension.dart';
import 'package:myapp/ui/values/resources.dart';
import 'package:flutter/material.dart';
class Application {
static GlobalKey<NavigatorState> navKey = GlobalKey();
static Resources get resources {
return navKey.currentContext.resources;
}
}
main.dart
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: Application.navKey,
...
And then:
import 'package:flutter/material.dart';
import 'package:myapp/application/application.dart';
class FavoritesPage extends StatefulWidget {
#override
_FavoritesPageState createState() => _FavoritesPageState();
}
class _FavoritesPageState extends State<FavoritesPage> {
#override
Widget build(BuildContext context) {
return Text(Application.resources.strings.hello);
}
}
Hope it helps!
First of all, create a new strings folder in assets and add your language JSON files.
assets
strings
- en.json
- ar.json
This is your en.json file
{
"title": "Flutter app"
}
And this is your ar.json file
{
"title": "تطبيق Flutter"
}
Then, change your pubspec.yaml file like below.
dependencies:
# your other codes
intl: ^0.17.0
flutter_localizations:
sdk: flutter
# your other codes
flutter:
uses-material-design: true
assets:
- assets/strings/en.json
- assets/strings/ar.json
After that, create AppLocalizations.dart class
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
class AppLocalizations {
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
String getText(String key) => language[key];
}
Map<String, dynamic> language;
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const AppLocalizationsDelegate();
#override
bool isSupported(Locale locale) => ['en', 'ar'].contains(locale.languageCode);
#override
Future<AppLocalizations> load(Locale locale) async {
String string = await rootBundle.loadString("assets/strings/${locale.languageCode}.json");
language = json.decode(string);
return SynchronousFuture<AppLocalizations>(AppLocalizations());
}
#override
bool shouldReload(AppLocalizationsDelegate old) => false;
}
Finally in your main.dart file make the below changes
void main() async {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: AppLocalizations.of(context).getText("title"),
locale: Locale("en"),
localizationsDelegates: [const AppLocalizationsDelegate()],
supportedLocales: [const Locale('en', ''), const Locale('ar', '')],
home: HomeScreen(),
);
}
}
create "Strings.dart" file and add the below line==>
class Strings
{
static String welcomeScreen="WelCome Page";
static String loadingMessage="Loading Please Wait...!";
}
And then call the file using the below line using the widget
Text(Strings.loadingMessage)
Make sure that the String.dart file has been imported
I use this method instead of using third party lib. Basically, I create a class that holds those values (string, colors, dimens, etc)
resources.dart
import 'dart:ui';
class ResString{
var data = {
'url' : 'https://facebook.com/',
'welcome' : 'Welcome Home',
};
String get(String key){
return data[key];
}
}
class ResColor{
var data = {
'colorPrimary' : 0xff652A04,
'colorPrimaryDark' : 0xffFFFFFF,
'colorPrimaryLight' : 0xffF6EDDD,
};
Color get(String key){
return Color(data[key]);
}
}
To use it, simply call the get method
main.dart
import 'package:my_app/resources.dart';
...
return Container(
color: ResColor().get('colorPrimary')
);
...
It's not funny to mange the languages at all, Android Studio have a build-in plugin of Transalte the words and let you mange it easy, so you can see in a table the Key of the word, and the result in every language you just add, manually of course. soon in Flutter I hope!
I tried some of the solutions suggested in this post, but the one from #Fakhriddin Abdullaev was the one that worked well for me. But I didn't like the fact that one must always lookup the key of each string in the.json files.
So I created a strings.dart:
import 'package:/AppLocalizations.dart';
class Strings {
static String error = "Error Message";
static AppLocalizations? locator = AppLocalizations();
// ignore: non_constant_identifier_names
static String app_name = locator?.getText("app_name") ?? error;
}
When there is an entry in the .json files like:
{
"app_name" : "My awesome AppName",
}
you just need to call strings. and the code completion will suggest needed string:
But do not forget to initialize Strings.locator with the correct context:
Strings.locator = AppLocalizations.of(context);
That is the correct way. In flutter you don't need .xml or .css files to manage your layout/stuff.
Everything is managed using the dart code. Which makes everything much easier.
I can't make a list with realm in order to use it with a realm ListView.
I need to make 2 or 3 ListViews, you can see the pieces of code below:
realm.js:
const Realm = require ('realm');
class UserEntrySchema extends Realm.Object {}
UserEntrySchema.schema = {
name:'User',
primaryKey:'id',
properties:{
id:'int',
name:'string',
username: 'string',
email: 'string',
}
};
class UserListSchema extends Realm.Object {}
UserListSchema.schema = {
name:'UserList',
properties: {
users :{type:'list', objectType:'User'}
}
};
class HistorySchema extends Realm.Object {}
HistorySchema.schema = {
name : 'History',
properties :{
items : {type:'list',objectType:'User'}
}
};
export default new Realm({
schema:[UserEntrySchema,UserListSchema,HistorySchema], schemaVersion:0});
I make a first ListView with the following code:
export default class SearchTabScreen1 extends Component {
constructor(props) {
super(props);
this.state = {
searchText:'',
data:[]
};
}
componentDidMount(){
this.fetchUsers();
}
fetchUsers(){
console.log("FEEEEEETCH");
fetch('http://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
data : responseJson
});
var data = this.state.data;
realm.write(() => {
for (var i = 0; i < data.length; i++){
let myUser = realm.create('User',data[i],true);
}
console.log("ALLUSER", realm.objects('User'));
});
})
.catch(function(e) { // Failure callback registartion
alert('Failure fetching data');
console.log(e)
});
}
I tried to make a list property using
UserListSchema
with no success.
And for now this ListView works fine even when I'm using
realm.objects('User')
as datasource.
I don't know if it's good to do it like that or not.
The second ListView is a "search history", when a row of the first ListView is clicked, it called the following method that pushes another screen (I am using react-native-navigation package) and populate a realm list. I would like to use this list as datasource for the 'history ListView".
onPushPress(rowData) {
this.props.navigator.showModal({
title: "Random Title",
screen: "Project.WordDefinition",
passProps: {
definition: rowData.name
}
});
realm.write(() => {
let historyList = realm.create('History',{},true);
historyList.items.push({rowData});
});
}
}
I got this error:
'Property' must be of type number
I also tried:
onPushPress(rowData) {
console.log("ROWDATA", rowData);
this.props.navigator.showModal({
title: "Titre",
screen: "AccessiDico.WordDefinition",
passProps: {
definition: rowData.name
}
});
realm.write(() => {
let historyList = realm.create('History',{},true);
historyList.items.push({
id:rowData.id,
name:rowData.name,
username: rowData.username,
email: rowData.email,
});
console.log("ROWDATA",rowData);
console.log("ITEMS",realm.objects('History'));
console.log("List",historyList.items);
});
}
}
And I got this error:
Attempting to create an object of type 'User' with an existing primary
key value
Does it means I can't use "my users" in the 'UserEntrySchema' to push them within a realm list ?
I would really appreciate some help, it has been a week that I am hard stuck with this :+1:
Thanks !
PS: Here how the history ListView is coded:
export default class HistoryTabScreen2 extends Component {
constructor(props) {
super(props);
// if you want to listen on navigator events, set this up
//this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
postDataSource: ds.cloneWithRows(realm.objects('History')),
};
}
renderRow(rowData, sectionId, rowId, highlightRow){
return(
<TouchableHighlight onPress={this.onPushPress.bind(this)}>
<View style={styles.row}>
<Text style={styles.rowText}>{rowData.name}</Text>
</View>
</TouchableHighlight>
)
}
render(){
return(
<ListView
dataSource={this.state.postDataSource}
renderRow={this.renderRow.bind(this)}
/>
);
}
And the log of my rowData when I clicked a row of the ListView:
'ROWDATA', { id: 5,
name: 'Chelsey Dietrich',
username: 'Kamren',
email: 'Lucio_Hettinger#annie.ca',
address:
{ street: 'Skiles Walks',
suite: 'Suite 351',
city: 'Roscoeview',
zipcode: '33263',
geo: { lat: '-31.8129', lng: '62.5342' } },
phone: '(254)954-1289',
website: 'demarco.info',
company:
{ name: 'Keebler LLC',
catchPhrase: 'User-centric fault-tolerant solution',
bs: 'revolutionize end-to-end systems' } }
I just responded to a question about list objects.
take a look at this link, and then ask for further clarification if you need it. At the end of the post I provided a working example of creating/modifying/appending/deleting objects from a realm List object.
How can I properly copy objects from one Realm object to another object
To create a list is pretty straightforward, here's the simplest case:
class Letters: Object {
var letterList = List<Letter>()
}
So to create a list, you need to know the Object subclass you will be using. (Letter in the above example).
To add to the list, you create an object (item - below), and then append to the list:
firstList.letterList.append(item)