Search code examples
react-nativedjango-rest-frameworkcrud

How to add an Update + Delete feature in my Details page in React Native? (DjangoRestFramework + React Native)?


My app is a CRUD React Native that interacts with Django Rest Framework based off of a book called "Building Versatile Mobile Apps with Python and REST: RESTful Web Services with Django and React". The project lets users enter in different data fields about pizza restaurants and display them.

I've been able to build the Crud web application in React and Django and a mobile app with Django and React native that only lets me add and read data.

I'm on the very last chapter and I'm about to deploy, but I don't know how to send update and delete requests in React Native to an API the book never covers this section. I added an update button but I don't know how to logically navigate to an edit section from the detail_view.js section.

Here is the open source code from the book on github

The Structure of the file looks like this

This is my app.js file

import React from 'react';
import { StyleSheet, Text, SafeAreaView, Image } from 'react-native';
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { createDrawerNavigator } from '@react-navigation/drawer';
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import ListView from "./src/screens/components/function_list_view";
import DetailView from "./src/screens/components/detail_view";
import AddPizzeria from "./src/screens/drawer/addPizzeria.js";
import RegForm from "./src/screens/drawer/regForm.js";
import LoginForm from "./src/screens/drawer/loginForm.js";
import TabOne from "./src/screens/tabs/tab1.js";
import TabTwo from "./src/screens/tabs/tab2.js";

const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();

renderTabComponents = () => (
  <Tab.Navigator>
    <Tab.Screen name="Tab 1" component={TabOne} />
    <Tab.Screen name="Tab 2" component={TabTwo} />
  </Tab.Navigator>
);

renderScreenComponents = () => (
  <Stack.Navigator>
    <Stack.Screen name="Home" component={ListView} />
    <Stack.Screen name="Detail" component={DetailView} />
    <Stack.Screen name="Tabs" children={this.renderTabComponents} />
  </Stack.Navigator>
);

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator>
        <Drawer.Screen name="Home" children={this.renderScreenComponents} />
        <Drawer.Screen name="Add Pizza" component={AddPizzeria} />
        <Drawer.Screen name="Registration" component={RegForm} />
        <Drawer.Screen name="Login" component={LoginForm} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  baseText: {
    color: "navy",
    fontSize: 30,
    fontStyle: "italic",
  },
  newText:{
    color: "red",
  },
  pizzaImage: {
    width: 200,
    height: 200,
  },
})

Here is my detailview file:

import React, { useState, useEffect } from "react";
import {View, Text, Image, FlatList } from "react-native";
import client from "./../../api/client";
import styles from "./detail_styles";

const DetailView = ({  route }) => {
    const [detail, setDetail] = useState("");
    const { objurl } = route.params;
   
    const getDetail = async (url) => {
        try {
          const response = await client.get(url);
          if (!response.ok) {
            setDetail(response.data);
          }
        } catch (error) {
          console.log(error);
        }
      };
    useEffect(()=>{
        getDetail(objurl);
    }, [])
    return (
        <View style={styles.center}>
        <FlatList
        horizontal={true}
        data={detail.pizzeria_images}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => {
          return (
            <Image
              style={styles.pizzaImage}
              source={{
                uri: item.image,
              }}
            />
          );
        }}
      />
      <Text style={styles.title}>Pizzeria: {detail.pizzeria_name}</Text>
      <Text style={styles.details}>Address: {detail.street}</Text>
      <Text style={styles.details}>
        City: {detail.city}, {detail.state},{detail.zip_code}
      </Text>
      <Text style={styles.details}>Web: {detail.website}</Text>
      <Text style={styles.details}>Ph: {detail.phone_number}</Text>
      <Text style={styles.details}>Description: {detail.description}</Text>
      <Text style={styles.details}>Email: {detail.email}</Text>
// this is where I want to edit the data fields
            <Button
                style={styles.addButton}
                onPress={() => *I don't know what to navigate*}
                title="Edit"
              />

    </View>
    );
  }

export default DetailView;

This is the addPizzeria.js file that submits the data

import React, {useState} from "react";
import { SafeAreaView, ScrollView, TextInput, Button, NativeModules,Text, Alert } from "react-native";
import { Formik } from "formik";
import client from "./../../api/client";
import styles from "./addPizzeria_styles";
import validationSchema from "./addPizzeria_valid";
import PhotoPicker from "../components/shared/photo.js";

const AddPizzeria = () => {
  const [photo, setPhoto] = useState("");
  const postedAlert = () => {
    Alert.alert("Success!", "Thank you! ", [
      {
        text: "Go to main screen",
        onPress: () => NativeModules.DevSettings.reload()
      },
    ]);
  };
  const handleSubmit = async (values) =>{
    const data = new FormData();
    data.append("pizzeria_name", values.pizzeria);
    data.append("street", values.street);
    data.append("city", values.city);
    data.append("state", values.state);
    data.append("zip_code", values.zip_code);
    data.append("website", values.website);
    data.append("phone_number", values.phone_number);
    data.append("pizzeria_name", values.pizzeria);
    data.append("description", values.description);
    data.append("email", values.email);
    data.append("logo_image", {
      uri: photo,
      name: "filename.jpg",
      type: "image/jpg",
    });
    try {
      const response = await client.post("api/create/", data); postedAlert();
    } catch(error) {
        console.log(error);
      };
  };
  
  return (
    <Formik
      initialValues={{
        pizzeria: "",
        street: "",
        city: "",
        state: "",
        zip_code: "",
        website: "",
        phone_number: "",
        description: "",
        email: "",
      }}
      onSubmit={handleSubmit}
      validationSchema={validationSchema}
    >
      {({ handleChange, handleSubmit, values, errors }) => (
        <SafeAreaView style={styles.content}>
          <ScrollView>
          <PhotoPicker photo={photo} onPressPhoto={(uri) => setPhoto(uri)} />
            <TextInput
              style={styles.textBox}
              value={values.pizzeria}
              placeholder="Enter a new pizz place here"
              onChangeText={handleChange("pizzeria")}
            />
            <Text style={styles.error}>{errors.pizzeria}</Text>
            <TextInput
              style={styles.textBox}
              value={values.street}
              placeholder="Street address"
              onChangeText={handleChange("street")}
            />
            <Text style={styles.error}>{errors.street}</Text>
            <TextInput
              style={styles.textBox}
              value={values.city}
              placeholder="City"
              onChangeText={handleChange("city")}
            />
          <Text style={styles.error}>{errors.city}</Text>
          <TextInput
              style={styles.textBox}
              value={values.state}
              placeholder="State"
              onChangeText={handleChange("state")}
            />
          <Text style={styles.error}>{errors.state}</Text>
          <TextInput
              style={styles.textBox}
              value={values.zip_code}
              placeholder="Zip"
              onChangeText={handleChange("zip_code")}
            />
          <Text style={styles.error}>{errors.zip_code}</Text>
          <TextInput
              style={styles.textBox}
              value={values.website}
              placeholder="Website"
              onChangeText={handleChange("website")}
            />
          <Text style={styles.error}>{errors.website}</Text>
          <TextInput
              style={styles.textBox}
              value={values.phone_number}
              placeholder="Phone number"
              onChangeText={handleChange("phone_number")}
            />
          <Text style={styles.error}>{errors.phone_number}</Text>
          <TextInput
              style={styles.textBox}
              value={values.description}
              placeholder="Description"
              onChangeText={handleChange("description")}
            />
          <Text style={styles.error}>{errors.description}</Text>
          <TextInput
              style={styles.textBox}
              value={values.email}
              placeholder="Email"
              onChangeText={handleChange("email")}
            />
          <Text style={styles.error}>{errors.email}</Text>
            <Button
              style={styles.addButton}
              onPress={handleSubmit}
              title="Submit"
            />
          </ScrollView>
        </SafeAreaView>
      )}
    </Formik>
    )}
export default AddPizzeria;

I tried creating an update file that is same as my addpizzeria file, but I get lost trying to plan out where and how to structure it so I can reference it when I make a request to update that data.

The only viable option is to make a feature on the detailview.js to update the data. This is what I'm trying and unsure of. I don't know where to go from here aside from adding an update and delete button on this page that navigates to another file and does the delete and update functions. your text


Solution

  • Ok I solved the issue. It seems the creator of the book added tabs in app.js in the Bottonnavigator class just in case you'd want to add and Update and Delete feature in detailview.js page.

    All that is needed is to just add the navigation.navigate("Tabs") in a button in my detailview.js file.

                <Button
                style={styles.addButton}
                title="Click for tabs"
                onPress={() => navigation.navigate("Tabs")}
              />