Form data is empty after using append? - laravel

I have a problem to append anything in form data. Its always empty. How can I append image file and some other data?
var data = new FormData();
fileResult = this.$els.fileIntroImage.files;
data.append('name',this.property_credentials.name);
data.append('default_image',this.$els.fileIntroImage.files[0],File);
console.log('data',data);

Took me a while to get my head around file uploads with Vue.
Here is the methods object on my Vue component:
methods: {
upload(e) {
e.preventDefault();
var self = this;
var formData = this.gatherFormData();
this.$http.post('/path/to/upload/method', formData)
.then(response => {
//do stuff
},
(response) => {
//show error
});
},
gatherFormData() {
const data = new FormData();
data.append('image', this.$refs.image.files[0]);
data.append('other_field', this.other_field);
return data;
}
},
This should then function as as a normal file field as far as Laravel is concerned.

It can be logged, you just need to log each item. You can use FormData’s iterator function to do so.
var data = new FormData();
data.append('name',this.property_credentials.name);
data.append('default_image',this.$els.fileIntroImage.files[0],File);
data.forEach(el => console.log(el));

Related

Can't post request with array parameter from vue to controller with axios

I'm trying to pass an array from my vue to my controller with axios post. But if I want to get the data from the request I don't get it with array format.
I tried it with an object also JSON.stringyfy() too.
The vue data I want to send
parts: [],
the axios post
const config = {
headers: {'content-type': 'multipart/form-data'}
};
let formData = new FormData();
formData.append('title', this.title);
formData.append('description', this.intro);
formData.append('parts[]', this.parts);
formData.append('pictures', this.selectedPictures);
formData.append('options', JSON.stringify(this.options));
valid = true;
if (valid) {
axios.post('/admin/oefeningen/oefening-opslaan', formData, config)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error.data);
});
}
Controller
public function save(Request $request)
{
try {
//get request info
return response($request->input('parts'));
} catch (\Exception $exception) {
return response($exception->getMessage());
}
}
Vue data I'm passing
parts = ["sdfsdfsdf", "sdfsdfsdfsfsdf"]
Result from response
sdfsdfsdf,sdfsdfsdfsfsdf (as string, not as array)
append for loop
let formData = new FormData();
formData.append('title', this.title);
formData.append('description', this.intro);
for (let i = 0; i < this.parts.length; i++) {
formData.append('parts', this.parts[i]);
}
I want to get the exact data in my controller as I have in my vue component. Like an array I can loop through.

Query additional API Endpoint with Axios & Vue after getting results from a different endpoint

I'm utilising the following API for a World Cup Laravel app - http://api.football-data.org/docs/v1/index.html#_fixture
This information brings me back today's fixture's as I'm using this code (config just holds my API key):
const todaysMatches = new Vue({
el: '#todaysMatches',
data: {
todaysMatches: [],
flags: []
},
methods: {
loadData: function () {
axios.get("http://api.football-data.org/v1/competitions/467/fixtures/?timeFrame=p1", config)
.then(response => {this.todaysMatches = response.data});
}
},
mounted: function () {
this.loadData();
}
});
This brings back the following data sctructure:
Inside each fixture you get an array of _links which you can see in the below screenshot:
Now, what I would like to do is query both the awayTeam api and the homeTeam api because they each have an endpoint of crestUrl which returns the country's flag.
You can see that inside my data I've set an array prop called flags so I was thinking of running additional calls inside my loadData method and populate that array for each fixture, but I don't think that's a clean way of doing it.
Can anyone suggest the best way to approach this?
I have used async/await pattern to achieve your requirement as below:
loadData: async function() {
const response = await axios.get(
"http://api.football-data.org/v1/competitions/467/fixtures/?timeFrame=p1",
config
);
this.todaysMatches = response.data;
let arr = this.todaysMatches.fixtures.map(fixture => {
const _links = fixture._links;
return [
axios.get(_links.awayTeam.href, config),
axios.get(_links.homeTeam.href, config)
];
});
arr.forEach(async item => {
const away = await item[0];
const home = await item[1];
this.flags.push({
awayFlag: away.data.crestUrl,
homeFlag: home.data.crestUrl
});
});
}
Explaination:
After fetching todaysMatches a new array arr is created which consists of promises returned by get request to the team's url [[getAwayTeamInfo, getHomeTeamInfo], [getAwayTeamInfo, getHomeTeamInfo], [getAwayTeamInfo, getHomeTeamInfo],...]
We loop through this and await on the promise to get the crestUrl
This crestUrl is pushed into flags array as an object
{
awayFlag: away.data.crestUrl,
homeFlag: home.data.crestUrl
}
Update
Adding the flag urls directly to the this.todaysMatches.fixtures array
loadData: async function() {
const response = await axios.get(
"http://api.football-data.org/v1/competitions/467/fixtures/?timeFrame=p1",
config
);
this.todaysMatches = response.data;
const fixtures = this.todaysMatches.fixtures;
let arr = fixtures.map(fixture => {
const _links = fixture._links;
return [
axios.get(_links.awayTeam.href, config),
axios.get(_links.homeTeam.href, config)
];
});
arr.forEach(async (item, index) => {
const away = await item[0];
const home = await item[1];
this.$set(fixtures, index, {
...fixtures[index],
awayFlag: away.data.crestUrl,
homeFlag: home.data.crestUrl
});
});
}

How to load a .csv file into crossfilter with d3?

I am trying to load a .csv file into crossfilter for further use it with dc.js and d3. However, if the ndx = crossfilter(data_) is not inside d3.csv(..., it does not work. Is it possible to load data using d3 inside a global/outside variable (in this case ndx)?
var ndx;
private method(){
var data_;
d3.csv("samples.csv", function(data){
var format = d3.timeParse("%m-%y");
data.forEach(function(d: any) {
d.date = format(d.date);
});
data_ = d3.csvParse(data);
});
ndx = crossfilter(data_);
}
How can I load it into crossfilter?
Am I obligated to use crossfilter inside the d3.csv(.. call?
Solution:
I made my .csv became a .json and I loaded it 'synchronously'. Observe below.
var ndx;
private method(){
var data_ = (function() {
var json: any = null;
$.ajax({
'async': false,
'global': false,
'url': "samples.json",
'dataType': "json",
'success': function (data:any) {
json = data;
}
});
return json;
})();
ndx = crossfilter(data_);
}
Observe:
'async': false
This happens because the callback function is executed asynchronously, once the data is returned. This means that if you put the charting code outside of the callback, you are going to get the empty array that you defined because no data has been returned yet.

Sending data to controller using Ajax

I have a form that contains different fields for user to fill in and also allow user to attach image. Below is my code to send data to the controller, I can see the image in my controller but I am not sure how to access rest of form data in controller:
$(function () {
var ajaxFormSubmit = function () {
var $form = $(this);
var data = new FormData();
var files = $("#File").get(0).files;
if (files.length > 0) { data.append("File", files[0]); }
else {
common.showNotification('warning', 'Please select file to upload.', 'top', 'right');
return false;
}
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: data,
processData: false,
dataType: "html",
contentType: false
};
$.ajax(options).done(function (data) {
$('#ProdList').html(data);
});
return false;
};
$("form[data-ajax='true']").submit(ajaxFormSubmit);
});
My controller :
public ActionResult Create(PostViewProduct postProduct)
{
//code......
}
PostViewProduct model shows only image fields with data rest showing null:
Do I have to add each field using formdata.append() or is there better way to send all the data to controller and then access the data in controller.
Thanks
Try this:
var data = new FormData($(this)[0]);
instead of var data = new FormData();
Try following, this will put the data in right format if all input is within the form.
data = $form.serialize();
You basically need to send the files in FormData along with other form element data.
$(function () {
var ajaxFormSubmit = function () {
var fdata = new FormData();
$('input[name="Image"]').each(function (a, b) {
var fileInput = $('input[name="Image"]')[a];
if (fileInput.files.length > 0) {
var file = fileInput.files[0];
fdata.append("Image", file);
}
});
// You can update the jquery selector to use a css class if you want
$("input[type='text'").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
var frmUrl = $(this).attr('action');
$.ajax({
type: 'post',
url: frmUrl,
data: fdata,
processData: false,
contentType: false,
success: function (e) {
console.log(e);
}
});
return false;
};
$("form[data-ajax='true']").submit(ajaxFormSubmit);
});
Assuming your view model has a property called Image of type HttpPostedFileBase for accepting the posted file and your form has an input for that
public class YourViewModel
{
public HttpPostedFileBase Image { set;get;}
//Your other existing properties
}
and your form has an file input tag with name "Image".
<input type="file" name="Image" />

Nativescript - Pass array from home-view-model to home.js

I´m having a hard time understanding how to perform this action(as the title says), and maybe someone could help me understand the process, my code is below:
My home-view-model:
var Observable = require("data/observable").Observable;
var ObservableArray = require("data/observable-array").ObservableArray;
var http = require("http");
function createViewModel() {
http.getJSON("http://myJsonfile").then(function (r) {
var arrNoticias = new ObservableArray(r.data);
return arrNoticias;
}, function (e) {
});
}
exports.createViewModel = createViewModel;
I have done a console.log of the arrNoticias before i have putted it inside a callback function and it returns [object object] etc...and then i have done this:
console.log(arrNoticias.getItem(0).titulo);
and it returns the info i need!.
Then in my home.js file i have this:
var observableModule = require("data/observable")
var ObservableArray = require("data/observable-array").ObservableArray;
var arrNoticias = require('./home-view-model.js');
console.log(arrNoticias.getItem(0).titulo);
and the result in the console is:
TypeError: arrNoticias.getItem is not a function. (In 'arrNoticias.getItem(0)', 'arrNoticias.getItem' is undefined)
My question is, how does this action is perform? passing the data from view-model to the .js file?
Thanks for your time
Regards
As that function send a URL request so probably it's an async function, which is on hold while requesting so that's why you get undefined. Normally, you will want your function that sends a URL request to return a promise. Based on that promise, you will the result as expected after the request is done. So:
function createViewModel() {
return new Promise<>((resolve, reject) => {
http.getJSON("http://myJsonfile").then(function (r) {
var arrNoticias = new ObservableArray(r.data);
resolve(arrNoticias);
}, function(e) {
reject(e);
});
}), (e) => {
console.log(e);
})
}
In home.js:
var homeVM= require('./home-view-model.js');
var arrNoticias;
homeVM.createViewModel().then(function(r) {
arrNoticias = r;
});

Resources