Développement d'applications mobiles

Développement d'applications mobiles


7- HTTP

8- Modèles

9.1- Recipeasy

Projet de départ

jsx
copier
import { Text, TextInput, View, Button } from 'react-native';
import { useState } from 'react';

export default function App() {
function handleLogin() {
}

return (
<View style={{ flex: 1, padding: 24, gap: 24 }}>

<TextInput placeholder="Username" style={{ borderWidth: 1 }} />
<TextInput placeholder="Password" style={{ borderWidth: 1 }} secureTextEntry />

<Button title="Login" onPress={ handleLogin }/>

</View>
);
}

Modèles

Pour encapsuler les données et comportements d'une entité de l'application, les classes permettent d'exploiter les concepts orienté-objet en JavaScript.

📚 Using classes

js
copier
class UserCredentials {

constructor({username, password}) {
this.username = username
this.password = password
}

}
js
copier
class User {

#id;

constructor({ id, username }) {
this.#id = id
this.username = username
}

get id() {
return this.#id
}

toJSON() {
return {
id: this.#id,
...this
}
}

}

Services

Pour encapsuler la manipulation des données de l'application, ex: CRUDL, en utilisant les modules, on obtient automatiquement le comportement d'un singleton.

📚 Modules

⬇️ Fichiers Martha

js
copier
class AuthService {
#currentUser = null // ATTENTION, à utiliser judicieusement

get currentUser() {
return this.#currentUser
}

async signUp(credentials) {
const response = await fetch("http://martha.jh.shawinigan.info/queries/insert-user/execute", {
method: 'POST',
body: JSON.stringify(credentials),
headers: {
'auth': 'ZGVtbzpSZWFjdE5hdGl2ZTIwMjQh'
}
}).then((r) => r.json())

if (response.success) {
this.#currentUser = new User({ id: response.lastInsertId, username: credentials.username })
}

return !!this.#currentUser
}

async logIn(credentials) {
const response = await fetch("http://martha.jh.shawinigan.info/queries/select-user-auth/execute", {
method: 'POST',
body: JSON.stringify(credentials),
headers: {
'auth': 'ZGVtbzpSZWFjdE5hdGl2ZTIwMjQh'
}
}).then((r) => r.json())

if (response.success && response.data.length == 1) {
const user = response.data[0]
this.#currentUser = new User({ id: user.id, username: user.username })
console.log(JSON.stringify(this.#currentUser))
} else {
this.#currentUser = null
}

return !!this.#currentUser
}

// ...
}

const service = new AuthService();
export default service;

Intégrer les modèles et services

Gérer l'état du modèle

jsx
copier
import UserCredentials from './UserCredentials.model.js'

export default function App() {
const [credentials, setCredentials] = useState(new UserCredentials({username: '', password: ''}))

async function handleLogin() {
console.log({credentials})
}

return (

<TextInput
value={ credentials.username }
onChangeText={ text => setCredentials(new UserCredentials({...credentials, username: text })) }
/>

<TextInput
value={ credentials.password }
onChangeText={ text => setCredentials(new UserCredentials({...credentials, password: text })) }
/>

);
}

Exploiter le service

jsx
copier
import auth from './Auth.service.js'

export default function App() {
const [credentials, setCredentials] = useState(new UserCredentials({username: '', password: ''}))

const [user, setUser] = useState()

async function handleLogin() {
console.log({credentials})

const success = await auth.logIn(credentials)

console.log({success, user: auth.currentUser})

setUser(auth.currentUser)
setCredentials(new UserCredentials({username: '', password: ''}))
}

function handleLogOut() {
auth.logOut()
setUser(auth.currentUser)
}

return (
<View style={{ flex: 1, padding: 24, gap: 24 }}>

{
user &&
<View>
<Text>{ JSON.stringify(user) }</Text>
<Button title="Log out" onPress={ handleLogOut }/>
</View>
}

</View>
);
}

Organisation

Par type
src
├── App.js
├── components
│   ├── StyledButton.js
│   └── StyledTextInput.js
├── models
│   ├── User.js
│   └── UserCredentials.js
├── screens
│   ├── auth
│   │   ├── Login.js
│   │   └── Signup.js
│   ├── recipes
│   │   ├── RecipeItem.js
│   │   ├── Recipe.js
│   │   └── Recipes.js
│   └── Screen.js
└── services
└── Auth.js
Par fonctionnalité
src
├── App.js
├── auth
│   ├── Auth.service.js
│   ├── Login.js
│   ├── Signup.js
│   ├── UserCredentials.model.js
│   └── User.model.js
├── components
│   ├── Screen.js
│   ├── StyledButton.js
│   └── StyledTextInput.js
└── recipes
├── RecipeItem.js
├── Recipe.js
├── Recipe.model.js
└── Recipes.js