How to addressing dynamic image path in react

But it seems there isn’t any linter plugin for visual studio

That’s the first Google result of many, you can add react-specifc linting rules as well, I don’t use visual studio though so you’d need to Google to see if there is a VS-specific thing you need to do

Fortunately, Visual Studio has EsLint itself. I just enabled it.
Here I use Toast UI Image Editor component.
And here comes the whole code:

import React, { useState, useEffect } from "react";
import "./ImageEditor.css";
import "tui-image-editor/dist/tui-image-editor.css";
import ImageEditor from "@toast-ui/react-image-editor";
import Button from "react-bootstrap/Button";
import ImageContext from "../ImageContext";

const icona = require("tui-image-editor/dist/svg/icon-a.svg");
const iconb = require("tui-image-editor/dist/svg/icon-b.svg");
const iconc = require("tui-image-editor/dist/svg/icon-c.svg");
const icond = require("tui-image-editor/dist/svg/icon-d.svg");
const download = require("downloadjs");
const myTheme = {
    "menu.backgroundColor": "white",
    "common.backgroundColor": "#151515",
    "downloadButton.backgroundColor": "white",
    "downloadButton.borderColor": "white",
    "downloadButton.color": "black",
    "menu.normalIcon.path": icond,
    "menu.activeIcon.path": iconb,
    "menu.disabledIcon.path": icona,
    "menu.hoverIcon.path": iconc,
};

export default function App() {


    const [imageSrc, setImageSrc] = useState("");
    const imageEditor = React.createRef();

    //using the context
    const currentImage = React.UseContext(ImageContext);



    const saveImageToDisk = () => {
        
        const imageEditorInst = imageEditor.current.imageEditorInst;
        const data = imageEditorInst.toDataURL();



        if (data) {
            const mimeType = data.split(";")[0];
            const extension = data.split(";")[0].split("/")[1];
            download(data, `image.${extension}`, mimeType);
        }
            

    };

    return (
        <ImageContext.Consumer>
            {context => (
        <div className="home-page">
            <div className="center">
                <h1>Photo Editor</h1>
                <Button className='button' onClick={saveImageToDisk}>Save Image to Disk</Button>
                </div>
                
                    <ImageEditor
                        includeUI={{
                            loadImage: {
                                path: context.path,
                                name: context,
                            },
                            theme: myTheme,
                            menu: ["crop", "flip", "rotate", "draw", "shape", "text", "filter"],
                            initMenu: "",
                            uiSize: {
                                height: `calc(100vh - 160px)`,
                            },
                            menuBarPosition: "bottom",
                        }}
                        cssMaxHeight={window.innerHeight}
                        cssMaxWidth={window.innerWidth}
                        selectionStyle={{
                            cornerSize: 20,
                            rotatingPointOffset: 70,
                        }}
                        usageStatistics={true}
                        ref={imageEditor}
                    />
               
                </div>
            )}
        </ImageContext.Consumer>
    );
   
}

But despite Eslint is enabled, but there is no highlighted code!
Need your opinion!

You still haven’t fixed one the issues mentioned.

It’s useContext, it’s case sensitive.

Can’t see the ImageContext provider code to see if you’ve fixed the issues there

I found that code and change it:

const currentImage = React.useContext(ImageContext);

But do you think this line of code is still needed?

loadImage: {
                                path: context.path,
                                name: context,
                            },

loadImage: {
path: context.path,
name: context,
},

The line of code you are using, that is how you get the object that it stored in the context. The value assigned to the variable you have named context is whatever is stored in the value prop of the provider.

An object in JavaScript is like this:

{
  name: "This is the name of an image",
  path: "path/to/image",
}

Context is a way to store an object in a component (a Provider) so that can be accessed further down the component tree (to an arbitrary depth) without needing to manually pass the values down as props through every component in-between. You give the provider component the object via the value prop.

So the thing you store in the context has to be an object

If you are trying to directly store a string, as you seem to be trying to do, then:

  1. it will break because a string is not an object, so the app will just error out, and
  2. even if it didn’t, what is context.path? If context is a string, how can it have the property path

Edit: why are you mixing native JS module syntax (import foo from "bar") with Node’s CommonJS syntax (const foo = require ("bar"))

My context as you see here :

const currentImage = React.useContext(ImageContext);

Is a variable to the name of an dynamic image.

The second one I need is the path of the image and I used context.path.

For loading an image into the image editor I need these:

loadImage: {
        path: 'img/sampleImage.jpg',
        name: 'SampleImage'
      },

Do you see something wrong?

What are you putting into the context? What is the thing you are passing to the value prop?

<ImageContext.Provider value={WHAT_IS_THIS} />

I don’t know how to phrase this any other way, but I will try again:

  • that value has to be an object, it cannot be a string. The only thing you are allowed to put there is an object.
  • that object is the thing you store in the context, it is the point of the context.
  • with const currentImage = React.useContext(ImageContext), the value of currentImage is that object.

If you are still trying to pass a string in as the value, it will not work. It will cause an error, and your app will fall over.

You could see the context provider code here:

//import axios from 'axios';
import React, { Component } from 'react';
import { Redirect } from "react-router-dom";
import ImageContext from '../ImageContext';


//import React, { useState } from 'react';


export default class ImageUpload extends Component {
    static displayName = ImageUpload.name;

    constructor(props) {
        super(props);
        this.state = {
            redirect: null,
            selectedFile: null,
            description: null,
            uploadResult: null,
            fileIdList: []
           
        };

        this.onNavToEditor = this.onNavToEditor.bind(this);
    }

    getList = () => {
        fetch('api/Image')
            .then(response => response.json())
            .then(data => this.setState({ fileIdList: data }));
    };

    componentDidMount() {
        this.getList();
    };

    onFileChange = event => {
        this.setState({ selectedFile: event.target.files[0] });
    };
    onDescriptionChange = event => {
        this.setState({ description: event.target.value })
    };
    onFileUpload = async () => {

        const formData = new FormData();

        formData.append(
            "ImageData.File",
            this.state.selectedFile,
            this.state.selectedFile.name
        );


        //try {

        fetch('/api/Image', {
            method: 'POST',
            body: formData
        }).then(resposne => resposne.json())
            .then(data => {
                console.log(data);
                this.setState({ uploadResult: "File " + data.fileName + " successfully uploaded." });
                this.getList();
            });
        //console.log(res);

        //} catch (ex) {
        //    console.log(ex);
        //}
    };


    onNavToEditor = async () => {

        //this.props.history.push
        //history.pu
        this.setState({ redirect: "/ImageEditor" });
      
        
    };

    //try {
    //    const res = await axios.post("Image/Image/Post", formData)
    //    console.log(res);

    //} catch (ex) {
    //    console.log(ex);
    //}
//};
 

    listItems = () => {
        const listItems = this.state.fileIdList.map((item) =>
            <div key={item.imageId.toString()}>
                <img src={"/api/Image/DownloadImage/" + item.imageId}
                    alt={item.fileName}
                    className="img-thumbnail"
                    height="100" width="100" />
            </div>
        );
        return (<div>{listItems}</div>);
    };

    render() {
        if (this.state.redirect) {
            return <Redirect to={this.state.redirect} />
        };
        const mystyle = {
            
            backgroundColor: "DodgerBlue",
            margin: "100px",
           
            height: "100px",
            width:"100px"

            
        };

        return (
            <ImageContext.provider value={this.state.selectedFile.name}>
            <div>
                <div style={mystyle} onClick={this.onNavToEditor}/>
                <h1>File Upload Demo</h1>
                <div >{this.state.uploadResult} onClick={this.onNavToEditor}</div>
                <div>
                    <input type="file" onChange={this.onFileChange} />
                    <input type="text" value={this.state.value} onChange={this.onDescriptionChange} />
                    <button onClick={this.onFileUpload}>
                        Upload!
                    </button>
                 
                </div>

                {this.listItems()}
               
                </div>
            </ImageContext.provider>
        );
    }
}

What changes should I make?

Capitalisation, again:

ImageContext.provider

The component is Provider, capital P, components are always capitalised.

And, again what is the value of this.state.selectedFile.name? Is it a string? If it is a string, this:

<ImageContext.Provider value={this.state.selectedFile.name}>

this will cause your app to error.

I changed the P.
What should I do with the provider?
My error from VS is here:

const ImageContext = React.CreateContext('null');

OK, you’re making very basic JS errors here – null is a type of value, "null" is a string. And you don’t seem to understand what I’m saying, which is that the prop that you have to pass to the provider has to be an object. The concept of components and props is React-specific, but the difference between a string and an object is very basic JS – they are completely different things. The impression I get is that you are copy pasting bits of code you have found, gluing them together without really understanding what the code is doing.

While we are primarily here to help people with their Free Code Camp progress, we are open to people on other paths, too. Some of what you are asking is pretty trivial in the Free Code Camp context, so you might find that if you’re not getting the instruction and material you need in your current studies, the FCC curriculum will really help you get started. At a modest guess, I’d say investing 4-5 hours working through the curriculum here will really pay off. You can find the curriculum at https://www.freecodecamp.org/learn.

With your current questions, we don’t have enough context to know what you already know or don’t know, so it is impossible to guide you without just telling you the answer (which we won’t do).

In the JavaScript section, “Basic JavaScript”, “ES6”, “Basic Data Structures” are likely to be most helpful, supported by the “Basic Algorithms” and “Intermediate Algorithms” challenges.

Then in the “Front End Development Libraries” section, there is a React course (and the React documentation itself is very good, and you should work through that).

It is also pretty typical on here for people to share a codepen / repl.it / jsfiddle example of what they have tried so that anyone helping has more of an idea of what help is actually helpful.

Happy coding :slight_smile:

2 Likes