Issue
I am making a demo login app using python framework-django, graphql, flutter like below.
This is a very simple app for a test but I'm getting "NoSuchMethodError='[]'", and I'm already spending a number of hours on this issue.
Error messages I am getting are below.
The user wants to create an account with [email protected] and dasdfadsf dart_sdk.js:28087
There was an error!
Uncaught (in promise) Error: NoSuchMethodError: '[]'
Dynamic call of null.
Receiver: null
Arguments: [0]
at Object.throw_ [as throw] (:58141/dart_sdk.js:5348)
at Object.defaultNoSuchMethod (:58141/dart_sdk.js:5793)
at Object.noSuchMethod (:58141/dart_sdk.js:5788)
at callNSM (:58141/dart_sdk.js:5521)
at Object._checkAndCall (:58141/dart_sdk.js:5523)
at Object.callMethod (:58141/dart_sdk.js:5601)
at Object.dsend (:58141/dart_sdk.js:5604)
at main._LoginPageState.new._createAccountPressed (:58141/packages/auth_frontend/main.dart.lib.js:1003)
at _createAccountPressed.next (<anonymous>)
at :58141/dart_sdk.js:39230
at _RootZone.runUnary (:58141/dart_sdk.js:39087)
at _FutureListener.thenAwait.handleValue (:58141/dart_sdk.js:34073)
at handleValueCallback (:58141/dart_sdk.js:34633)
at Function._propagateToListeners (:58141/dart_sdk.js:34671)
at _Future.new.[_completeWithValue] (:58141/dart_sdk.js:34513)
at async._AsyncCallbackEntry.new.callback (:58141/dart_sdk.js:34536)
at Object._microtaskLoop (:58141/dart_sdk.js:39374)
at _startMicrotaskLoop (:58141/dart_sdk.js:39380)
at :58141/dart_sdk.js:34887
Flutter doctor result is below
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.2.3, on Microsoft Windows [Version 10.0.19043.1165], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Android Studio (version 4.1.0)
[√] VS Code (version 1.60.0)
[√] Connected device (2 available)
• No issues found!
My flutter project code is below (I excluded unimportant lines) <main.dart>
import 'package:flutter/material.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:graphql_flutter/graphql_flutter.dart';
import 'graphql_config.dart';
import 'graphql_query.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(
GraphQLProvider(
client: GraphQLConfiguration.initializeClient(),
child: CacheProvider(child: MyApp()),
),
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My first Django plus Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: LoginPage(),
);
}
}
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
enum FormType { login, register }
class _LoginPageState extends State<LoginPage> {
GraphQLConfiguration graphQLConfiguration = GraphQLConfiguration();
QueryMutation addMutation = QueryMutation();
final TextEditingController _emailFilter = TextEditingController();
final TextEditingController _passwordFilter = TextEditingController();
String _email = "";
String _password = "";
FormType _form = FormType.login;
_LoginPageState() {
_emailFilter.addListener(_emailListen);
_passwordFilter.addListener(_passwordListen);
}
void _emailListen() {
if (_emailFilter.text.isEmpty) {
_email = "";
} else {
_email = _emailFilter.text;
}
}
void _passwordListen() {
if (_passwordFilter.text.isEmpty) {
_password = "";
} else {
_password = _passwordFilter.text;
}
}
....
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Python & Flutter Login by Hong"),
centerTitle: true,
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
_buildTextFields(),
_buildButtons(),
],
),
),
);
}
Widget _buildTextFields() {
return Container(
child: Column(
children: <Widget>[
Container(
child: TextField(
controller: _emailFilter,
decoration: InputDecoration(labelText: 'Email'),
),
),
Container(
child: TextField(
controller: _passwordFilter,
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
),
)
],
),
);
}
Widget _buildButtons() {
if (_form == FormType.login) {
return Container(
child: Column(
children: <Widget>[
ElevatedButton(
child: Text('Login'),
onPressed: _loginPressed,
),
TextButton(
child: Text('Don have an account? Tap here to register'),
onPressed: _formChange,
),
TextButton(
child: Text('Forgot Password?'),
onPressed: _passwordReset,
),
],
));
} else {
return Container(
child: Column(
children: <Widget>[
ElevatedButton(
child: Text('Create an Account'),
onPressed: _createAccountPressed,
),
TextButton(
child: Text('Don have an account? Tap here to login'),
onPressed: _formChange,
),
],
));
}
}
...
void _createAccountPressed() async {
print('The user wants to create an account with $_email and $_password');
GraphQLClient _client = graphQLConfiguration.clientToQuery();
QueryResult result = await _client.mutate(
MutationOptions(
// ignore: deprecated_member_use
document: addMutation.register('$_email', '', '$_password'),
),
);
if (result.data["success"] != null) {
print('The user was created successfully!');
} else {
print('There was an error!');
print(result.data["register"]["errors"]["email"][0]["message"]);
}
}
...
}
<graphql_config.dart>
import "package:flutter/material.dart";
// ignore: import_of_legacy_library_into_null_safe
import 'package:graphql_flutter/graphql_flutter.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:shared_preferences/shared_preferences.dart';
class GraphQLConfiguration {
static final HttpLink httpLink = HttpLink(
uri: "http://127.0.0.1:8000/graphql",
);
static final AuthLink authLink = AuthLink(getToken: () async {
SharedPreferences pref = await SharedPreferences.getInstance();
return pref.getString("token");
});
static final Link link = authLink.concat(httpLink);
static ValueNotifier<GraphQLClient> initializeClient() {
ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
link: link,
cache: OptimisticCache(dataIdFromObject: typenameDataIdFromObject),
),
);
return client;
}
GraphQLClient clientToQuery() {
return GraphQLClient(
link: link,
cache: OptimisticCache(dataIdFromObject: typenameDataIdFromObject),
);
}
}
<graphql_query.dart>
class QueryMutation {
String register(String email, String user, String password) {
return """
mutation {
register(
email: "$email",
username: "$user",
password1: "$password",
password2: "$password",
) {
success,
errors,
token,
refreshToken
}
}
""";
}
}
<settings.py - django>
"""
Generated by 'django-admin startproject' using Django 3.2.7.
...
"""
from pathlib import Path
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'graphene_django',
'graphql_jwt.refresh_token.apps.RefreshTokenConfig',
"graphql_auth",
'django_filters',
'corsheaders',
]
AUTH_USER_MODEL = 'users.CustomUser'
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True
GRAPHENE = {
'SCHEMA': 'auth2.schema.schema', # this file doesn't exist yet
'MIDDLEWARE': [
'graphql_jwt.middleware.JSONWebTokenMiddleware',
],
}
GRAPHQL_JWT = {
"JWT_VERIFY_EXPIRATION": True,
# optional
"JWT_LONG_RUNNING_REFRESH_TOKEN": True,
"JWT_ALLOW_ANY_CLASSES": [
"graphql_auth.mutations.Register",
],
}
AUTHENTICATION_BACKENDS = [
# 'graphql_jwt.backends.JSONWebTokenBackend',
'django.contrib.auth.backends.ModelBackend',
"graphql_auth.backends.GraphQLAuthBackend",
]
EMAIL_BACKEND ='django.core.mail.backends.console.EmailBackend'
ROOT_URLCONF = 'auth2.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'auth2.wsgi.application'
DATABASES = {
'default': {
...
}
}
AUTH_PASSWORD_VALIDATORS = [
...
]
...
I'm assuming there is something wrong with async/await things but I am not too sure about it. I've been trying a number of ways, but it seems like it's even getting more complicated.
Any advice would highly be appreciated!
Solution
I believe you made a typo in main.dart here and you should go into your map like this:
if ((result.data["mutation"])["success"] != null) {
...
}
it should be success not sucess.
Also, for accessing maps you should be aware to use parenthesis when neccessary:
print((((((result.data["register"])["errors"])["email"])[0])["message"]));
Answered By - Benyamin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.