Laravel Attach Files Duplicates Database Record - mysql

I am using: Laravel, Vue JS, dropzone.
Works fine with one file being uploaded but when 3 files are uploaded it create a new homework record, like so:
Homework ID: 1, Files: 1, 2
Homework ID: 2, Files: 3
Should look like:
Homework ID: 1, Files: 1,2,3
Code for upload is the following:
public function store() {
$data = request()->validate([
'title' => '',
'description' => '',
'start_date' => '',
'due_date' => '',
'group_id' => '',
'dropzonefile' => '',
'live_status' => '',
]);
// Create homework record...
$task = request()->user()->homeworks()->create([
'title' => $data['title'],
'description' => $data['description'],
'start_date' => $data['start_date'],
'due_date' => $data['due_date'],
'live_status' => $data['live_status'],
]);
// Add homework to some groups...
$task->groups()->attach(Arr::pluck(json_decode($data['group_id']), 'group_id'));
// Upload all files...
if (isset($data['dropzonefile'])) {
foreach ($data['dropzonefile'] as $attachment) {
$attachmentName = $attachment->store('userFiles', 'public');
$attachmentInfo = request()->user()->attachments()->create([
'reference_name' => $attachmentName,
'original_file_name' => $attachment->getClientOriginalName(),
]);
$task->attachments()->attach($attachmentInfo->id);
}
}
return new TaskResource($task);
}
Front End Code:
dropzoneOptions: {
paramName: "dropzonefile",
url: '/api/homework',
thumbnailWidth: 150,
maxFilesize: 20,
maxFiles: 5,
addRemoveLinks: true,
uploadMultiple: true,
autoProcessQueue: false,
headers: {
'X-CSRF-TOKEN': document.head.querySelector('meta[name=csrf-token]').content,
},
sending: (file, xhr, formData) => {
formData.append('title', this.taskTitle);
formData.append('description', this.content);
formData.append('start_date', this.selectedSetDate);
formData.append('due_date', this.selectedDueDate);
formData.append('group_id', JSON.stringify(this.value));
formData.append('live_status', this.liveStatus);
},
success: (event, res) => {
// alert('success');
console.log(event);
this.makeToast(true,'info');
this.$router.push('/Teacher')
}
},

I think I found the answer:
upload multiple files in one request Dropzone sending two requests
Seems like I was missing some dropzone options:
autoDiscover: false,
parallelUploads: 10,

Related

How can i upload image file and data object with axios in Vue & Laravel?

I'm struggling to upload an image and several text/numeric data fields to a MySQL DB with Vue, Laravel, and Axios.
Here's the method in my Vue component:
addProductToShop() {
const imageData = this.$refs.inputUpload.files[0];
const formData = new FormData();
formData.append("image", imageData);
axios
.post("api/createProduct", {
formData,
...this.newProduct
})
.then(res => {
console.log(res);
});
},
And here's the method in my Laravel controller:
public function create(Request $request)
{
$product = Product::create([
'name' => $request->name,
'price' => $request->price,
'amountInStock' => $request->amountInStock,
'image' => $request->image->store('ProductImages', 'public'),
'measuringUnitId' => $request->measuringUnitId,
'categoryId' => $request->categoryId,
'shopId' => $request->shopId,
]);
return response()->json([
'status' => 'success',
'message' => 'Product added seccessfully',
'product' => $product
], 200);
}
Here's the request body in telescope:
{
"formData": [],
"name": "111",
"categoryId": null,
"price": "111",
"amountInStock": "111",
"measuringUnitId": 2,
"visability": true
}
And here's the error that i'm getting: Call to a member function store() on null
I've tried adding multi-form data headers:
headers: {
'Content-Type': 'multipart/form-data'
}
However, they generated this error: Missing boundary in multipart/form-data POST data in Unknown on line 0
So, they seem obsolete now, because axios knows the corrent formData based on the FormData().
Can someone point out what am i doing wrong? Thanks in advance!
Error here:
'image' => $request->image->store('ProductImages', 'public')
Correct way:
'image' => $request->file('image')->store('ProductImages', 'public')

About CakePHP 3 BelongsToMany issue

I have an issue with the following case :
Users Table
id, profile_id, name, created, modified
Profiles Table
id, first_name, last_name, gender
Businesses table
id, name, created, modified
I have a relation table many to many to link profiles to businesses : businesses_profiles
id, business_id, profile_id, created, modified
When i try to create a new business, I would like to link directly logged in user profile id to the business I'm creating.
in my profileTable, I've added in initialize() :
$this->belongsToMany('Businesses', [
'alias' => 'Businesses',
'foreignKey' => 'profile_id',
'targetForeignKey' => 'business_id',
'joinTable' => 'businesses_profiles'
]);
in my businessesTable, I've also put in initialize() method:
$this->belongsToMany('Profiles', [
'alias' => 'Profiles',
'foreignKey' => 'business_id',
'targetForeignKey' => 'profile_id',
'joinTable' => 'businesses_profiles'
]);
In each entities Business & Profile, I put respectively in right context :
protected $_accessible = [
'*' => true,
'id' => false,
'businesses' => true,
'_joinData' => true
];
and :
protected $_accessible = [
'name' => true,
'slug' => true,
'active' => true,
'hash' => true,
'data' => true,
'approved' => true,
'created' => true,
'modified' => true,
'profiles' => true,
'_joinData' => true
];
Nothings work about saving in my businesses_profiles table.
Thanks in advance for your help,
Best,
Laurent.
Thanks a lot for your help. I've found the solution by using the link() method provided by CakePHP.
I'll share my add function here, if it can help others :
public function add()
{
$business = $this->Businesses->newEntity();
if ($this->request->is('post')) {
$business = $this->Businesses->patchEntity($business, $this->request->getData());
$business->set('hash');
$business->set('active', 0);
$business->set('slug');
$profile = TableRegistry::getTableLocator()->get('Profiles')->get($this->_currentUser->profile_id);
if ($this->Businesses->save($business)) {
**$this->Businesses->Profiles->link($business, [$profile]);**
$this->Flash->success(__('The business has been saved.'));
return $this->redirect(['action' => 'index']);
}
else
{
debug($business->getErrors()); // debug
$this->Flash->error(__('The business could not be saved. Please, try again.'));
}
}
$this->set(compact('business'));
}

Dropdown in list data

This is my code:
[
'attribute' => 'status',
'value' => function ($model) {
return Html::dropDownList('status', ['10' => 'Active', '20' => 'Deactive']);
},
],
I just want dropdown in status column. If record is active or deactive it will be selected.
You need to use 'format' => 'raw' for the column options and your definition for the dropDownList() is wrong you need to have the selection string as the second parameter and the dropdown options as the third parameter. Change your code to below:
[
'attribute' => 'status',
'format' => 'raw',
'value' => function ($model) {
return Html::dropDownList('status', $model->status, ['10' => 'Active', '20' => 'Deactive']);
},
],
EDIT
You didnt had in the initial requirements that you waned to update the status too when the drop down is changed. You can bind ajax call to the drop-down.
Add the following javascript on top of your view where you are initializing the GridView.
NOTE: Change the url:'controller/update-status?id'+id in the ajax call to the relative controller where you want to update the status for the row, but dont remove the id
$js = <<<JS
$(document).on('ready pjax:success',function(){
$(".switch-status").on('change',function(){
var data={};
data[$(this).attr("name")]=$(this).val();
var id=$(this).closest("tr").data('key');
$.ajax({
method:'post',
url:'/controller/update-status?id='+id,
data:data,
success:function(data){
if(!data.success){
alert(data.message);
}else{
alert("Status updated.");
}
},
error:function(jqXHR, textStatus, errorThrown ){
alert(errorThrown);
}
});
});
});
JS;
$this->registerJs($js, yii\web\View::POS_END);
Then inside your GridView column for status change the dropdown to the following
return Html::dropDownList(Html::getInputName($model, 'active'), $model->active, [10 => 'Active', 20 => 'Deactive'], ['class' => 'switch-status']);
And the go to your controller and add the action code for updating the status
Note: Change the Model in the first line $model = Model::findOne($id); name with the respective model you are using.
public function actionUpdateStatus($id) {
$model = Affiliate::findOne($id);
$app = Yii::$app;
$request = $app->request;
if($request->IsAjax && $request->isPost) {
Yii::$app->response->format = Response::FORMAT_JSON;
if($model->load($request->post()) && $model->save()) {
return ['success' => true];
} else {
return [
'success' => false,
'message' => implode('<br />', ArrayHelper::getColumn($model->errors, '0'))
];
}
}
}
Use content property to render HTML elements. For example:
[
'attribute' => 'status',
'content' => function ($model) {
return Html::dropDownList('status', $model->status, ['10' => 'Active', '20' => 'Deactive']);
},
],

React-Native render json from fetch

I have a fetch returning on ComponentDidMount(). Trying to get the response to render on the page.
I have set the state as follows:
this.state = {
loading: true,
file: null,
video: null,
marks: []
};
and my fetch:
componentDidMount() {
return fetch('http://10.0.2.2:8080/marks/createMark')
.then(response => response.json())
.then((data) => {
this.setState({
loading: false,
marks: data.mark
}, () => {
console.log(data.mark);
console.log(this.state.marks);
// const dataMap = data.mark.map((item) => {
// return {
// key: item.id,
// label: item.mark
// };
// });
});
})
.catch(err => console.log(err));
}
Now my render inside of the return:
const { marks } = this.state;
<FlatList
data={marks}
renderItem={({ item }) => <Text>{item.mark}</Text>}
keyExtractor={(item, index) => index}
/>
Do I have to map the data then try to render it??
OUTPUT OF console.log(this.state.marks):
{ _id: '5b61e47a55a0000aa980fab1', mark: 'ItHe', __v: 0 }
The mark is a pseudorandom string that can contain letters and numbers created on the backend
As this.state.marks is an object. First, you need to convert it to this form [{}]. You can do the following changes to make it work.
fetch('http://10.0.2.2:8080/marks/createMark')
.then(response => response.json())
.then((data) => {
let marks = [data.mark]; //Add this line
this.setState({
loading: false,
marks: marks // Change this line
}, () => {
....
Rest of your code
marks is an array but you're not sharing what each object in the array looks like. If it's an array of strings, you're good but if it's an object, you'll need to destructure it and pull out the string you're looking to render.
<Text>{item.mark.someKeyWhoseValueIsAString}</Text

How to Integrate JSON API from website

I have been assigned to integrate API for my client website. This API is provided by vision6.com.au. There is no much information avialble on their website. Can anyone give me one example which will contact vision6 database and add a contact from our website developed using jquery and php.
Here is the way I am trying
var newVal = {
"id": 1,
"method": "addUser",
"params": [
"APIKEY",
"123456",
{
"username" : "username_123",
"password" : "123456abc",
"first_name" : "First Name",
"last_name" : "Last Name",
"email" : "example#example.com",
"mobile" : "0412312312",
"phone" : "56565656",
"fax" : "57575757",
"position" : "Manager",
"is_read_only" : true,
"timezone" : "Australia/Brisbane",
"email_user" : true,
"is_confirmed" : true
}
]
};
$.ajax({
url: 'http://www.vision6.com.au/api/jsonrpcserver.php?version=3.0',
type: 'POST',
beforeSend: function(){alert('sending');},
data: newVal,
//dataType: 'json',
//data: JSON.stringify(newVal),
//contentType: 'application/json; charset=utf-8',
dataType: 'json',
//async: false,
success: function(msg) { alert(msg);
}
});
This is what I have taken from their documentation
developers.vision6.com.au
For those who wants to integrate using Ruby, I've created a gist with a simple code:
require 'httparty'
url = 'http://www.vision6.com.au/api/jsonrpcserver.php?version=3.0'
api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
JSON.parse(HTTParty.post(url, headers: { 'Content-Type' => 'application/json' }, body: JSON.dump({
'method' => 'getSessionInfo', 'params' => [api_key]
})))
JSON.parse(HTTParty.post(url, headers: { 'Content-Type' => 'application/json' }, body: JSON.dump({
'method' => 'searchLists', 'params' => [api_key]
})))
list_id = 123456
JSON.parse(HTTParty.post(url, headers: { 'Content-Type' => 'application/json' }, body: JSON.dump({
'method' => 'addContacts', 'params' => [api_key, list_id, [{ 'First Name' => 'Foo', 'Last Name' => 'Bar', 'Email' => 'foo#bar.com' }]]
})))
You will need to download a jsonRPCClient.php and include it in your php file. From my dealings with the Vision6 API, its not very comprehensive and doesn't make much sense until you start getting into it more. Unfortunately, they aren't very helpful in getting you started.
My code to get you started
include 'includes/jsonRPCClient.php';
$list_id = 1234;
$url = "http://www.vision6.com.au/api/jsonrpcserver.php?version=3.0";
$apikey = 'YOURAPIKEYHERE'
$api = new JsonRpcClient($url);
$contact = array();
$contact[] = array(
'First Name' => "John",
'Email' => "sample#email.com"
);
$returnID = $api->addContacts($apikey, $list_id, $contact);
the most important change I found was
$api->addContacts($apikey, $list_id, $contact);
All methods using the API follow this structure
$api ->APIMethod($apikey, $OtherRequiredFields/Arrays);
I suggest to follow their documentation
http://developers.vision6.com.au/3.0/guide/getting-started
Documentation mentions a client library to access their JSON-RPC. Download it, create a free account and generate a working snippet of PHP code from their examples. It also seems to contain a lot of insights and examples. I am just quoting PHP code for addbatch
// setup vars
$list_id01 = 123;
$list_id02 = 456;
$message_id = 111;
$batch_details = array
(array
('list_id' => $list_id01,
'type' => 'list', // all Contacts in List 123
'time' => 'send, // populate Batch time of send
)
array
('list_id' => $list_id02,
'type' => 'contact', // send to contact_list, next
'contact_list' => array(2),array(17),array(18),
'time' => 'send, // populate Batch time of send
));
$queue_id = $api->invokeMethod('addBatch', $message_id, $batch_details,
time() + (24*3600), true);
Once you produce a snippet of code that does an authorization request and a simple action, but DOES NOT behave as you expected you should update your question on SO. I.e. you should post the snippet and the results that you get vs. the results that you expect to get. That might really help to tackle the problem.
I would also recommend to contact support of the service directly.
PS
Unless you will be able to ask a question in form that would be potentially useful to other users, It would be very difficult to get an answer that you seek. Otherwise your question can be qualified as too localized.
<?php
$data = array(www.mtalkz.com)
‘dest’ => ‘0000000000’,
‘msg’=>’This is Test message’,
‘pass’=>’xyz’,
‘send’=>’ALERTS’,
‘uname’=>’ xyz ‘,
‘wapurl’=>’www.mtalkz.com‘
);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => “https://mtalkz.com/developer-tools/“,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => “”,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => “POST”,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => array(
“cache-control: no-cache”,
“content-type: multipart/form-data”,
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo “cURL Error #:” . $err;
} else {
echo $response;
}
<?php
$data = array(www.mtalkz.com)
‘dest’ => ‘0000000000’,
‘msg’=>’This is Test message’,
‘pass’=>’xyz’,
‘send’=>’ALERTS’,
‘uname’=>’ xyz ‘,
‘wapurl’=>’www.mtalkz.com‘
);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => “https://mtalkz.com/developer-tools/“,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => “”,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => “POST”,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => array(
“cache-control: no-cache”,
“content-type: multipart/form-data”,
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo “cURL Error #:” . $err;
} else {
echo $response;
}