An app functionality doen't work when I deploy it


#1

Hello, everyone.
I have a form containing three text fields. The first has a fixed value, the second is modifiable, the third is not modifiable, but its value is calculated as the second is modified. I used the react components as mentioned above.

this is my form:


AI



NI



Montant {/*montantFacture */}

constructor(props) {
super(props);
this.state = {montantValeur: 0};
this.montantFacture = this.montantFacture.bind(this);
this.modifMontant = this.modifMontant.bind(this)
}

/* Function called to calculate the third texfield value /
montantFacture(){
const {tempons, EventState} = this.props;
const selectedCat = EventState.get(‘SELECTION’);
//console.log(EventState.get(‘SELECTION’));
let montant = 0;
tempons.map(temponInfo =>{
if(EventState.get(‘SELECTION’) !== undefined){
if(temponInfo.categoryId == selectedCat._id){
const tarif = selectedCat.tarification;
const aindex = parseInt(temponInfo.aindex);
let nindex = 0;
if(parseInt(('#formField6').val()) == null || isNaN((’#formField6’).val())){
nindex = 0;
}else{
nindex = parseInt(('#formField6').val()); } parseInt((’#formField6’).val());
montant = (nindex - aindex)
tarif;
}
}
this.setState({montantValeur: montant});
//return this.montantValeur;
});
}

async componentDidUpdate(){
const {tempons, EventState} = this.props;

     let indexform = parseInt($('#formField5').val());
     tempons.map(temponInfo =>{
           if(EventState.get('DEP_FORM') == undefined){
                 if(temponInfo.categoryId == EventState.get('CAT_SELECTED')) {
                      if(indexform !== temponInfo.aindex){
                            //if(EventState.set('MODIFICATION_DEPENSE') !== true){
                            $('#formField5').val(temponInfo.aindex);
                            $('#formField6').val(temponInfo.aindex);
                            //}
                      }
                 }
           }
     });
}

async componentWillUnmount(){
      this.setState({montantValeur: 0});
}

async componentDidMount(){
const {EventState} = this.props;
$("#formField2").value = setInterval(
() => this.montantFacture(),
1000
);
}

Everything goes well during development, but once the application is deployed, it is impossible to retrieve the value of the third text field. Need some help please


#2

Please edit your post and wrap all code between triple-backticks:

```
code
goes
here
```

#3

[quote=“nylfortune, post:1, topic:47125”]
thank you robfallos. Hope that everything is right now

/* this is my form: */
<div className="form-group ">
          <label htmlFor="formField5"> AI </label>
          <input type="number" ref="AIndex" defaultValue={parseInt(indexform)} 
              id="formField5" autoComplete="true" className="form-control" disabled='true'/>
 </div>
<div className="form-group ">
          <label htmlFor="formField6"> NI </label>
          <input type="number" ref="NIndex" placeholder="NI" id="formField6" defaultValue=
             {parseInt(indexform)} autoComplete="true" className="form-control" />
 </div>

<div className="form-group ">
          <label htmlFor="formField2"> Montant </label>   
          <input type="number" ref="MRef" id="formField2" autoComplete="true" 
              className="form-control" value={this.state.montantValeur} disabled='true' />
 </div>
constructor(props) {
super(props);
this.state = {montantValeur: 0};
this.montantFacture = this.montantFacture.bind(this);
this.modifMontant = this.modifMontant.bind(this)
}

/* Function called to calculate the third texfield value */
montantFacture(){
const {tempons, EventState} = this.props;
const selectedCat = EventState.get(‘SELECTION’);
//console.log(EventState.get(‘SELECTION’));
let montant = 0;
tempons.map(temponInfo =&gt;{
if(EventState.get(‘SELECTION’) !== undefined){
if(temponInfo.categoryId == selectedCat._id){
const tarif = selectedCat.tarification;
const aindex = parseInt(temponInfo.aindex);
let nindex = 0;
if(parseInt(('#formField6').val()) == null || isNaN((’#formField6’).val())){
nindex = 0;
}else{
nindex = parseInt(('#formField6').val()); } parseInt((’#formField6’).val());
montant = (nindex - aindex)</em> tarif;
}
}
this.setState({montantValeur: montant});
//return this.montantValeur;
});
}

async componentDidUpdate(){
const {tempons, EventState} = this.props;
     let indexform = parseInt($('#formField5').val());
     tempons.map(temponInfo =>{
           if(EventState.get('DEP_FORM') == undefined){
                 if(temponInfo.categoryId == EventState.get('CAT_SELECTED')) {
                      if(indexform !== temponInfo.aindex){
                            //if(EventState.set('MODIFICATION_DEPENSE') !== true){
                            $('#formField5').val(temponInfo.aindex);
                            $('#formField6').val(temponInfo.aindex);
                            //}
                      }
                 }
           }
     });
}

async componentWillUnmount(){
      this.setState({montantValeur: 0});
}

async componentDidMount(){
const {EventState} = this.props;
$("#formField2").value = setInterval(
() =&gt; this.montantFacture(),
1000
);
}

Everything goes well during development, but once the application is deployed, it is impossible to retrieve the value of the third text field. Need some help please


#4

The code is hard to read frankly.

But you are mixing jQuery with React to read the input, that would be the first thing to fix, yon use react refs to read the inputs, see here. So that’s where I’d start, I’d also isolate just the reading of the input and test it in production and console that, because you’ve the input parsing wrapped in if statements and it’s hard to tell where is the issue is.

In productions, it’s either there is no jQuery or some other error, but it’s hard to tell from the snippet you provided. So, you need to simplify the form, use react refs and isolate the issue by process of elimination.


#5

Thank U. I’m going to try it. Hope that it will work


#6

Before testing, I would like to point out that Jquery is working for other functions.


#7

I know it’s works, I just don’t recommend mixing it with React.

It’s not really needed when using react since you’ll be mostly using React to manage the DOM and it’ll unnecessary increase your bundlesize.


#8

before we can dig into the actual problem, i recommend you to:

  • fix the code styling above, it’s still nearly unreadable
  • do some more tutorials about react
  • do not mix jquery with react (already mentioned)
  • use ESLINT
  • use prettier
  • don’t call setState in componentWillUnmount, that makes no sense.
  • also the componentDidMount above makes no sense to me.
  • don’t use setInterval like you do
  • if you really need setInterval (i doubt it), don’t forget to call clearInterval in componentWillUnmount
  • learn the difference between array .map and .forEach

#10

I agree with that using jquery is unnecessary in this case. But I used it before it did’nt work with refs. Now I remember done my first tests not with jquery. But, unfortunately, it didn’t work. Now, I decided to abandon jquery again, it is not necessary.


#11

The code style above is just a set of excerpts from the problem I wanted to present to you. It is not possible, from this post, to view the organization of my code. In fact, I use the Mantra architecture, and my form and its constructor are in a rather large React component. If you think it is not necessary to use the componentDidMount and the setInterval, where and how do I call the function that changes the value of the third field as the second field is edited? If you wish, I can isolate this code in a component and send it to you for better readability. I know the difference between array .map and .forEach, and I chose to use .map. Do you really think it could be a problem here? Why?


#12

please present us at least the whole component with the render function.

its constructor are in a rather large React component.

so maybe break it apart first and refactor it.

If you think it is not necessary to use the componentDidMount and the setInterval, where and how do I call the function that changes the value of the third field as the second field is edited?

React works by changing props and state. You never ever directly manipulate dom-elements. Instead in your render function you do something like:

// ... in your render function
<input type="number" value={this.state.value1} onChange={this.onValue1Change} />
<input type="number" value={this.state.value2} onChange={this.onValue2Change} />
<input type="number" disabled value={this.calculateValue3}  /> { /* acutally, if the user does not need to change value 3, you can also just use a span, p or whatever */}

so if onValue1Change or onValue2Change is called, you calculate value3 with some function.

I know the difference between array .map and .forEach, and I chose to use .map. Do you really think it could be a problem here? Why?

no, its not the problem, but it makes the code harder to reason about, because it is semantically wrong and could show some lack of javascript knowledge. Why did you chose to use map? (map is to transform an array into another one, forEach is to do side effects). That’s also why i would recommend some code style checker like eslint.


#13

@macrozone has covered most of it, and time consuming though it may be to get some of that stuff configured (if you’ve never done it before), it will save you hours of time every week/month. I highly recommend it.

As for your original question, the way you describe it, there needs to be only one single input (for value 2). If value 1 is fixed, then why isn’t it being hardcoded (or loaded from the database)?

Value 2 needs to be modifiable, of course.

Value 3 can be updated as a part of the onChange of value2’s input.

Here is a simple implementation of the above (keeping in mind it is just one of many possible ways to do it): https://codesandbox.io/s/yv5o0nykm9

import React, { Component } from 'react';

class Example extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value2: '',
      value3: '',
    }
    this.setValue2 = this.setValue2.bind(this);
  }
  
  setValue2(e) {
    const value2 = e.target.value;
    const value3 = value2 + 'whatever calculation is needed to create value 3 can go here' // can use a function too...
    this.setState({value2, value3});
  }

  render() {
    const value1 = 'Value 1' // Load this from the db or hard code it, whatever
    const { value2, value3 } = this.state;
    return (
      <div>
        <p>{value1}</p>
        <input type="text" value={value2} onChange={this.setValue2} />
        <p>{value3}</p>
      </div>
    );
  }
}

export default Example;

#14

As a small addition, i would calculate value3 in the render instead of in state, because it is dependent on value1.

In general, i would always “normalize” state, similar like in database modelling (https://en.wikipedia.org/wiki/Database_normalization).


#15

Thanks, guys. For @hemalrr87 and @macrozone, value1 is not a state, but come from the database. The default value of value2 is value1, but this value2 is modifiable. I’ll try your proposals, then I’ll come back to you with a more readable code extract. I’m working on it. I am currently eliminating the parts that are not relevant to my question.


#16

I have aanother problem with my app. Unable to test the deploy app since I update my meteor version to 1?8.0.2. I receive this error: POST http://192.168.100.2/meteor/dynamic-import/fetch net::ERR_CONNECTION_REFUSED. I’ve been desperately looking for the solution for several days.


#17

For the previous problem, I deleted the use of the setInterval, and I’m testing the solution of @hemalr87


#18

Note that this error only appears in production: POST http://localhost/meteor/dynamic-import/fetch net::ERR_CONNECTION_REFUSED


#19

you need to define the environment variable ROOT_URL on your production server

see also https://docs.meteor.com/environment-variables.html


#20

I defined it in my nginx server like this: ROOT_URL=http://localhost


#21

that’s why it does not work :wink:

you have to specify the public url:

ROOT_URL=https://www.myfancyapp.com