File upload in React using formik and laravel as a backend - reactjs

I am new to react and I am trying to upload a file to my project. All is going well except when I am sending a file request to the backend it shows empty [] to that particular file.
This is how I am trying to send the value. In this values consists of an object of all the input fields in my form whose initial values are set as null.
const initialValues = {
fy_id: "",
main_chalani_no: "",
section_chalani_no: "",
department_id: "",
chalani_basis: "",
darta_id: "",
main_chalani_date: "",
section_chalani_date: "",
letter_no: "",
letter_date: "",
chalani_office: "",
subject: "",
chalani_type: "",
chalani_medium: "",
medium_dtl: "",
file_one: "",
file_two: ""
};
<input className="form-control" name="file_one" type="file"
onChange={e => {
if (e.target.files && e.target.files.length > 0)
{
setAvatarPreview(URL.createObjectURL(e.target.files[0]));
}
console.log(e.currentTarget.files[0]);
values.file_name = e.currentTarget.files[0];
}}
/>
Console.log is returning the file Console.log ss
And in the laravel I can get all the values but not file die and dump ss
If anybody could help me out I would be grateful and sorry for my question if I had made mistakes on them and could not make it clear as possible

Related

React dropdown in table - duplicating values into other columns

I have React menu planning application (personal use only) which is a table of 7 columns for each day, 3 rows for lunch, dessert and dinner. In lunch and dinner row there is several dropdowns for type of meals, in dessert row there is just one column. Image attached below for better view. The meals can appear repetedly.
Now the problem - the person which is using it mostly on iPhone is complainng that when he fills the menu selecting values from dropdowns, sometimes (yes that is what I get from hit, nothing more) the app replaces values in all columns with data from one columns. The menu then looks like each week same meals. The problem is that has never occured to me though I tested the app upside down. But I test it only on Chrome - Win and Android (thought it does not seems like browser-related problem).
What I did to get to the bottom of this:
Add Error boundary: no error occured
Carefully go through key chaining in for loops in render method and make sure every dropdown has unique key
I kind of do not know which code to include. So this is part of the render method for the table:
{
TYPES.map((type, typeIndex) => (
<tr className={type === DESSERTTYPE ? "dessertRow" : ""} key={"type"+typeIndex}>
{days.map((day, dayIndex) => (
<td key={"day"+typeIndex+""+dayIndex}>
{
CATEGORIES.map((category, categoryIndex) => (
this.getMealComponent(type, category, dayIndex, "category"+typeIndex+""+dayIndex+""+categoryIndex)
))
}
</td>
))}
</tr>
))
}
And this is code to get the meal component:
getMealComponent(type, category, dayIndex, key) {
switch(type) {
case LUNCH:
case DINNER:
if(category === DESSERT) return;
return <MealsDrop key={key} keyToShow={key} selectedMenu={this.state.selectedMenu} dayTime={type} meals={this.getMeals(category)} day={dayIndex} handleMealsDropChange={this.dropChange} category={category} />;
case DESSERTTYPE:
if(category === DESSERT) {
return <MealsDrop key={key} keyToShow={key} selectedMenu={this.state.selectedMenu} dayTime={type} meals={this.getMeals(DESSERT)} day={dayIndex} handleMealsDropChange={this.dropChange} category={category} />;
}
break;
default:
return "";
}
}
I am thinking about rewriting the app because the person this app is for changed his mind about the app working several times and at the end it completely changed the flow of the app. But first I need to get to the bottom of this problem.
What else this could be the problem
structure of the selected menu could make available the mistake. But I cannot find the right place where it is. The selected menu is array of 7 items this structure:
MEALOBJECT = {
lunch: {
soup: "",
soupnote: "",
rice: "",
longcook: "",
lcnote: "",
protein: "",
pnote: "",
salad: "",
saladnote: "",
vege: "",
vnote: "",
seaweed: "",
note: ""
},
dessert: "",
dinner:{
soup: "",
soupnote: "",
rice: "",
longcook: "",
lcnote: "",
protein: "",
pnote: "",
salad: "",
saladnote: "",
vege: "",
vnote: "",
seaweed: "",
note: ""
}```
Anyone has had a problem like this? Is there a cure or should I include the link to whole project for the complex code? Thanks guys in advance to look at this. I am pointless now for looking into the code for few evenings.
Menu planning application - the table structure

Checkbox not reflecting changes in the state in ReactJS

I cannot get my reactjs component to reflect the actual changes in state on a checkbox. Could anyone kindly assist or point out what is wrong with my code below.
This is my state
state = {
data: {
name: "",
address: "",
city: "",
country: "",
mobile_number: "",
description: "",
has_conference: false,
star_rating: "",
},
errors: {},
};
This handle checkbox method
toggleChange = () => {
this.setState({
has_conference: !this.state.data["has_conference"],
});
};
And finally the checkbox code in render method
<label>
<input
type="checkbox"
has_conference={this.state.data["has_conference"]}
onChange={this.toggleChange}
/>
Conferencing
</label>
There are two things to correct in your code.
1: In toggleChange you dont change this.state.data.has_conference, but you change this.state.has_conference which is not exists in initial state. For changing this.state.data.has_conference you need to do following in your toggleChange function:
let data = this.state.data
data.has_conference = !data.has_conference
this.setState({data})
2: In you need to bind your this.state.data.has_conference value to the checked attribute. In code you need to write:
<input type="checkbox" onChange={this.toggleChange} checked={this.state.data.has_conference}
Hope this help.

Cannot read property 'name' of null on default value

I have a state in which i have
I had initialized my data state as null
For whole code visit
https://codeshare.io/5zMyXD
Calling aixos api request on componentDidMount
axios.post("http://localhost/axios1/index.php",data)
.then(res=>this.setState({data:res.data},
()=>console.log(this.state.data)))
Getting this on state
{id: "1", name: "vivek", fname: "modi", mobile: "9024555623", photo: "http://localhost/axios1/uploaded/student/rhinoslider-sprite.png"}
fname: "modi"
id: "1"
mobile: "9024555623"
name: "vivek"
photo: "http://localhost/axios1/uploaded/student/rhinoslider-sprite.png"
<input defaultValue={this.state.data.name} />
how to set these values in it's input like input for name input for fname
{id: "1", name: "vivek", fname: "modi", mobile: "9024555623", photo: "http://localhost/axios1/uploaded/student/rhinoslider-sprite.png"}
fname: "modi"
id: "1"
mobile: "9024555623"
name: "vivek"
photo: "http://localhost/axios1/uploaded/student/rhinoslider-sprite.png"
<input defaultValue={this.state.data.name} />
Just use name from state
as if the object you mentioned is state then you can directly access state keys from state
like
this.state.name || this.state.mobile
You need to show your code in order to get better help but
If you have a correct state you can change values like this:
<input type="text" name="fname" value={this.state.data.name}>
But your state is null and the code you showed has problem, you need to fill your state correctly, in your class you can write:
State={name:"test"}
And it will work fine. Hope this can help you
update now write this:
{this.state.data && this.state.data.name
&& ( < input defaultValue={this.state.data.name} /> )}
You can set like call your axios request through
componentDidMount(){
axios.post("http://localhost/axios1/index.php",data)
.then(res=>this.setState({data:res.data},
()=>console.log(this.state.data)))
}
Suppose you are getting this in your state
state={
data:{
id: "1",
name: "vivek",
fname: "modi",
mobile: "9024555623",
photo: "http://localhost/axios1/uploaded/student/rhinoslider-sprite.png"
}
}
and then render it as
render(){
const {name,fname} = this.state.data?this.state.data:"";
return(
<div>
<input defaultValue={this.state.name} />
<input defaultValue={this.state.fname} />
</div>
);
}
Change this in your code, line no 31
this.setState({res.data},()=>console.log(this.state))

Working with angular cached array object

So I create a cached json object within an array with the following method in Angular:
$scope.saveClaim = function() {
//always set isOffset to false - empty string does not work for non-string objects in web api when field is required
$scope.claimInfo.isOffset = false;
$scope.claimsSubmit.push($scope.claimInfo);
//clears scope so form is empty
$scope.claimInfo = {
id: "",
benefitId: "",
isSecIns: "",
isNoResId: "",
expenseTypeId: "",
fromDate: "",
toDate: "",
provider: "",
who: "",
depId: "",
age: "",
amount: "",
comments: "",
isOffset: ""
};
}
The idea is the user fills out a form, and at the end either selects to add another claim or submit a claim (the object). After each time the form is filled and user selects file or add another, the form clears and the user then enters more data. The results is an array of object(s) that look like:
[
{
"id": "",
"benefitId": "",
"isSecIns": "",
"isNoResId": "",
"expenseTypeId": "",
"fromDate": "",
"toDate": "",
"provider": "",
"who": "",
"depId": "",
"age": "",
"amount": "",
"comments": "",
"isOffset": false
}
]
If more than one claim is entered, then we get multiple objects with same properties.
Each claim is then displayed with limited data in info boxes that display only 3-4 of the properties.
So I am trying to figure best way to do 3 things. First, add a unique "id" to each object. Second, if the delete icon in the info box selected, then remove that object from the array and if the "edit" icon is selected in the info box, then all the relative properties that that object in the array is populated back to the form.
Googling best tries for this, but not sure how I can work with the json objects this for for now. Can some of you help me on this?
Thanks much.
Hard to give the best way. Probably comes down to your style and preferences. But here is one way to do it, to get you going.
Define your model. It will contain the claim that is bound to the form and an array of added claims.
$scope.viewModel = {
claim: {},
claims: []
};
Add a function that assigns a claim object with default values:
var resetClaim = function() {
$scope.viewModel.claim = {
name: '',
city: ''
};
};
resetClaim();
The form elements will use ng-model:
<input type="text" model="viewModel.claim.name">
We will use ng-repeat to show the added claims:
<tr ng-repeat="claim in viewModel.claims">
Our form will have two buttons:
<button type="submit" ng-click="saveClaim()">Save Claim</button>
<button type="button" ng-click="cancel()">Cancel</button>
The cancel button will just reset the form.
The saveClaim function will look like this:
$scope.saveClaim = function() {
if (!isValidClaim()) return;
$scope.viewModel.claim.id ? updateClaim() : saveNewClaim();
resetClaim();
};
The isValidClaim function just checks if we have entered the requied fields. You could use form validation for this instead.
In this solution when saving a claim it could either be a new claim or an existing one that we have edited, and what we will do in the two cases will differ, so we need a way to tell what we are doing. Here we just check if it has an id. If it hasn't - it's a new claim. If it has, it's an existing.
To save a new claim we will do the following:
var saveNewClaim = function() {
var newClaim = angular.copy($scope.viewModel.claim);
newClaim.id = id++;
$scope.viewModel.claims.push(newClaim);
};
Note that it's important that we use for example angular.copy to create a new copy of the claim that is bound to the view. Otherwise we would just push a reference to the same object to the claims array which is not good since we want to reset one of them.
In this example id is just a variable starting at 0 that we increment each time we create a new claim.
Each element in our ng-repeat will have an edit and a remove icon:
<tr ng-repeat="claim in viewModel.claims">
<th>{{claim.id}}</th>
<td>{{claim.name}}</td>
<td>{{claim.city}}</td>
<td><i class="glyphicon glyphicon-edit" ng-click="editClaim(claim)"></i></td>
<td><i class="glyphicon glyphicon-remove" ng-click="removeClaim(claim)"></i></td>
</tr>
The removeClaim function simply takes a claim and removes it from the array:
$scope.removeClaim = function(claim) {
var index = $scope.viewModel.claims.indexOf(claim);
$scope.viewModel.claims.splice(index, 1);
};
The editClaim function will make a copy of the claim to edit and put it in the variable that is bound to the form:
$scope.editClaim = function(claim) {
$scope.viewModel.claim = angular.copy(claim);
};
You can also do the following:
$scope.viewModel.claim = claim;
And when you edit the claim in the form it will update in the ng-repeat at the same time. But then you have no good way of canceling and the save button wouldn't be needed. So it depends on how you want it to work.
If you edit the claim in the form now and save, we will come back to the saveClaim function:
$scope.saveClaim = function() {
if (!isValidClaim()) return;
$scope.viewModel.claim.id ? updateClaim() : saveNewClaim();
resetClaim();
};
This time the claim will have an id, so the updateClaim function will execute:
var updateClaim = function() {
var claim = $scope.viewModel.claims.filter(function(c) {
return c.id === $scope.viewModel.claim.id;
})[0];
angular.extend(claim, $scope.viewModel.claim);
};
It will retrieve the claim that we are editing from the claims array based on the id. We need to do this since we used angular.copy earlier and have two difference objects.
We will then use angular.extend to move all the new edited values to the claim that we pressed edit on in the ng-repeat.
Demo: http://plnkr.co/edit/yuNcZo7nUyxVsOyPTBEd?p=preview

How to print to view 1 object multilevel

I use AngularJS. How to print to view 1 object multilevel when I haven't defined the inside attributes.
For example, I have object error:
{
"email": {
"Required": []
},
"first_name": {
"Min": [
"2"
]
},
"last_name": {
"Required": []
}
}
I want to print all the data in this object formed list
email: Required
first_name:Min 2
last_name: Required
...
Please imagine that this is just one part in many errors that may happens when submitting form.
The DOT notation of reading objects or properties nested deep within an existing object works with AngularJS too.
Let us say you have the following object:
$scope.newObject = {
email: {
required: true
},
firstName: {
min: 2
}.
lastName: {
required: true
}
};
If you wish to then access the required property of the nested email object, then you can access it like so:
<input type="text" ng-required="newObject.email.required">
Thus using the DOT notation, we can access the nested objects and their properties too.
<ul>
<li ng-repeat="obj in newObject">
<span >{{obj.email.required}}</span>
<span >{{obj.email.firstname.min}}</span>
<span >{{obj.email.lastname.required}}</span>
</li>
</ul>
I hope this may help you

Resources