1

I have two components Display.jsx and DisplayList.jsx. Components work together to display values from local storage. The problem is with DisplayList.JSX handleEdit() method slicing.

Github project

My thoughts:

I asked on this forum how to delete local storage value and got this answer without explanation: stack overflow question

data = [
   ...data.slice(0, index),
   ...data.slice(index + 1)
 ];

It works but now I need to do similar slicing to edit and replace old storage value with new one. But I have no idea how to do it.

Summarize: In DisplayList.jsx In method handleEdit() need to take value from local storage and overwrite with this.state email and this.state password values.Bonus if somebody could explain the process.

Display.jsx

import React, { Component } from 'react'
import {DisplayList} from './DisplayList';


class Display extends Component {
  constructor(props){
    let data = JSON.parse(localStorage.getItem('data'));
    super(props)
    this.state = {
      data: data,
  }

  // Methods
  this.displayValues = this.displayValues.bind(this);
  }

  displayValues(){

   return this.state.data.map((data1, index) =>
    <DisplayList
      key = {index}
      email = {data1.email}
      password = {data1.password}
      updateList = {this.updateList}
       /> 
    )

  }
  // This is the method that will be called from the child component.
  updateList = (data) => {
    this.setState({
      data
    });
  }
  render() {
    return (
      <ul className="list-group">
        {this.displayValues()}
      </ul>
    )
  }
}

export default Display;

DisplayList.jsx

import React, { Component } from 'react'
import {Button, Modal, Form} from 'react-bootstrap';


export class DisplayList extends Component {

    constructor(props){
        super(props)
        this.state = {
            email: '',
            password: '',
            show: false,
        };

        // Methods
        this.handleDelete = this.handleDelete.bind(this);
        this.onChange = this.onChange.bind(this);
        // Edit Modal
        this.handleShow = this.handleShow.bind(this);
        this.handleClose = this.handleClose.bind(this);
        this.handleEdit = this.handleEdit.bind(this);
    }

    onChange(event){
        this.setState({
            [event.target.name]: event.target.value
        })
    };
    handleClose(){
        this.setState({show: false});
    }
    handleShow(){
        this.setState({show: true});
    }
    handleEdit(event){
        event.preventDefault();
        this.setState({show: false});
        let data = JSON.parse(localStorage.getItem('data'));

        for (let index = 0; index < data.length; index++) {
          if( this.props.email === data[index].email &&
              this.props.password === data[index].password){
        }
      }
          localStorage.setItem('data', JSON.stringify(data));
          this.props.updateList(data);
    }
    handleDelete(){
        let data = JSON.parse(localStorage.getItem('data'));
        for (let index = 0; index < data.length; index++) {
            if(this.props.email === data[index].email &&
                this.props.password === data[index].password){

                data = [
                  ...data.slice(0, index),
                  ...data.slice(index + 1)
                ];

            }
        }
        localStorage.setItem('data', JSON.stringify(data));
        this.props.updateList(data);
    }


  render() {
    return (
    <div className = "mt-4">
        <li className="list-group-item text-justify">
            Email: {this.props.email} 
            <br /> 
            Password: {this.props.password}
            <br /> 
            <Button onClick = {this.handleShow} variant = "info mr-4 mt-1">Edit</Button>
            <Button onClick = {this.handleDelete} variant = "danger mt-1">Delete</Button>
        </li>
        <Modal show={this.state.show} onHide={this.handleClose}>
          <Modal.Header closeButton>
            <Modal.Title>Edit Form</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <Form>
                <Form.Group controlId="formBasicEmail">
                <Form.Label>Email address</Form.Label>
                <Form.Control 
                autoComplete="email" required
                name = "email"
                type="email" 
                placeholder="Enter email"
                value = {this.state.email}
                onChange = {event => this.onChange(event)}
                />
                </Form.Group>
                <Form.Group controlId="formBasicPassword">
                <Form.Label>Password</Form.Label>
                <Form.Control 
                autoComplete="email" required
                name = "password"
                type="password" 
                placeholder="Password"
                value = {this.state.password}
                onChange = {event => this.onChange(event)}
                />
                </Form.Group>
          </Form>
          </Modal.Body>
          <Modal.Footer>
            <Button variant="secondary" onClick={this.handleClose}>
              Close
            </Button>
            <Button variant="primary" onClick={this.handleEdit}>
              Save Changes
            </Button>
          </Modal.Footer>
        </Modal>
    </div>
    )
  }
}
Arnas Dičkus
  • 371
  • 5
  • 19
  • There's no 'editing' `localStorage`... You can simply overwrite the existing value that you've set with another... More info about local storage: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage – SakoBu Feb 21 '19 at 18:58
  • Yes, I'am aware that I can't edit local storage. I plan to use slice values. Similarly how I done with handleDelete(). I just don't know how. The answer I'am expecting to be is in handleEdit() if statement. And it should look close to my handleDelete() data = [ ...data.slice(0, index), ...data.slice(index + 1) ]; answer – Arnas Dičkus Feb 21 '19 at 19:06
  • The main issue here is jumping into a lib or framework without first understanding the fundamentals of the language (javascript) that it was built on top of... It's like trying to write a novel without first learning the alphabet and putting together basic sentences... My honest advice is to learn the language first... – SakoBu Feb 21 '19 at 19:54
  • @SakoBu I disagree. I been programming for 10 months and my biggest javascript personal project is Budgety https://github.com/ArnasDickus/Budgety. Budget app application created with object orientated mvc patterns. I don't think it's accurate to say that I don't know JavaScript fundamentals because I asked about rest parameter and slicing data. I'm curious what do you mean by 'learn the language first'? Do you have a checklist of JavaScript features I should know before jumping into react? Thanks for the answer. – Arnas Dičkus Feb 22 '19 at 08:21

1 Answers1

2

While editing the data in localStorage, first get the value from localStorage, search the index of the value if it exits and then update the value at that index.

You can do this in multiple ways, but I find mapping over the list the easiest way to achieve this

handleEdit(event){
    event.preventDefault();
    this.setState({show: false});
    let data = JSON.parse(localStorage.getItem('data'));

    data = data.map((value) => {
         // check if this is the value to be edited
         if (value.email === this.props.email && value.password = this.props.password) {
              // return the updated value 
              return {
                   ...value,
                   email: this.state.email,
                   password: this.state.password
              }
         }
         // otherwise return the original value without editing
         return value;
    })
    localStorage.setItem('data', JSON.stringify(data));
    this.props.updateList(data);
}

To understand the above code you need to know what ... does. In a gist it is called Spread syntax and it allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected. You can read this post as well to know more about it

What does three dots do in ReactJS

Now to go through the code

{
    ...value, // spread the original value object 
    email: this.state.email, // override email value from value object with state.email
    password: this.state.password // override password value from value object with state.password
}
Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318
  • For some reason returning does not override original value. Everything else works well. [github project](https://github.com/ArnasDickus/enigma-assignment/blob/master/src/components/DisplayList.jsx) – Arnas Dičkus Feb 22 '19 at 13:12
  • Updated the answer, basically you need to assign the value returned by map to something.Change the code to `data = data.map((value) => {` – Shubham Khatri Feb 22 '19 at 13:14