I'm trying to follow this example code https://laravel.com/docs/7.x/broadcasting#using-example-application
I already made a controller with this code:
public function send()
{
$orderId = 5;
broadcast(new TestEvento($orderId));
return view('test.send');
}
public function receive()
{
$orderId = 5;
return view('test.receive', compact('orderId'));
}
An event with this code:
public $orderId;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($orderId)
{
$this->orderId = $orderId;
Log::debug('Construct orderId: '.$orderId);
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
Log::debug('broadcastOn: '.$this->orderId);
return new PrivateChannel('canaltest.'.$this->orderId);
}
A route:
Broadcast::channel('canaltest.{var}', function ($user, $var) {
return true; //temp workaround
return $user->id === Order::findOrNew($var)->user_id;
});
A view with this:
<div id="app">
<test :orderId="{{$orderId}}"></test>
</div>
Added this line to app.js:
Vue.component('test', require('./components/Test.vue').default);
And a .vue with
<script>
export default {
mounted() {
console.log('Component mounted.');
}
}
Echo.private('canaltest.${orderId}')
.listen('TestEvento', (e) => {
console.log(e);
});
</script>
The problem is I just can't find a way to get the js to get the orderId var and there's nowhere in vue documentation that says where should I place the .props array when requiring a component in app.js. So how can I get my test.vue component to read the orderId var?
I believe what you're looking for as below for test.vue
<script>
export default {
props: {
orderId: {
type: [Number, String],
required: true
},
},
mounted() {
console.log('Component mounted.');
}
}
</script>
Related
I'm new on Laravel development and started to build a small application for uploading images via form and drag and drop.
For some reason, when I try to upload an image using the POST route and the Controller's store method, the app only returns ERROR 405 - Method Not Allowed. I don't know why it's happening.
web.php
Route::resource('colaboradores', ColaboradoresController::class, ['only' => ['index', 'store', 'update', 'destroy']]);
My dropzone:
<form enctype="multipart/form-data" action="{{ route('administrativo.secoes.colaboradores.store') }}" id="image-upload-form">
<input type="file" name="file" id="image-input" class="dropzone-input" onchange="get_images(this)" multiple hidden>
<div class="drop-zone" id="image-dropzone" ondragover="dragOverHandler(event);" ondrop="dropHandler(event);">
<div class="inner-elements">
<label for="image-input">
<h3>Drag your pictures here</h3>
<span class="note needsclick">Or click here to manually select them.</span>
</label>
</div>
</div>
</form>
My JavaScript file with HTTP request through AJAX:
function dragOverHandler(ev) {
document.getElementById("image-dropzone").style.border = "3px solid #00f752";
ev.preventDefault();
}
function dropHandler(ev) {
document.getElementById("image-dropzone").style.border = "3px dashed #0087f7";
ev.preventDefault();
if (ev.dataTransfer.items) {
\[...ev.dataTransfer.items\].forEach((item, i) =\> {
if (item.type.includes("image")) {
const file = item.getAsFile();
upload_image(file);
}
});
}
}
function get_images() {
var total_images = document.getElementById("image-input").files.length;
if (total_images \> 0) {
for (var index = 0; index \< total_imagens; index++) {
var file = document.getElementById("image-input").files\[index\];
upload_image(file);
}
}
}
function upload_image(file) {
var form_data = new FormData();
form_data.append("file", file);
form_data.append("test", "test");
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $("meta\[name='csrf-token'\]").attr("content")
}
});
$.ajax({
type: "PUT",
url: \`${window.location.pathname}/store/\`,
data: form_data,
cache: false,
contentType: false,
processData: false,
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
}
});
}
SobreController.php
<?php
namespace App\Http\Controllers\Administrativo;
use App\Http\Controllers\Controller;
use App\Models\SectionCollaborators;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
class ColaboradoresController extends Controller
{
public function index()
{
//
}
public function create()
{
//
}
public function store(Request $request)
{
try {
$novo_nome = self::upload_imagem($request);
return response()->json(["imagem" => "$novo_nome", "mensagem" => "Imagem salva com sucesso."] 200);
} catch (Exception $e) {
return response()->json(["mensagem" => "Ocorreu um erro ao salvar a imagem. Tente novamente.", 500]);
}
}
private function upload_imagem(Request $request)
{
if ($request->hasFile('file') && $request->file('file')->isValid()) {
$request->validate([
'file' => 'required|image|mimes:jpeg,png,jpg,webm,svg|max:2048',
]);
$img = $request->file;
$novo_nome = Storage::disk('local')->put('public/img/colaboradores/cards', $img, 'public');
return basename($novo_nome);
}
}
public function update(Request $request)
{
//
}
private function update_text($object, $nome, $valor)
{
//
}
public function destroy(Request $request)
{
//
}
public function setId(int $value)
{
//
}
public function getId()
{
//
}
}
I have a chart, I am adding data through a controller. How do I add data via an event?
I have a database, through the controller I get the data, then I transfer it to the view and using the diagrams I display the data. I need to pass data through an event, how can this be done?
Chart:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [{
label: 'data',
data: [],
borderWidth: 1
}]
},
options: {
scales: {
xAxes: [],
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
var updateChart = function() {
$.ajax({
url: "{{ route('chart') }}",
type: 'GET',
dataType: 'json',
success: function(data) {
myChart.data.labels = data.labels;
myChart.data.datasets[0].data = data.data;
myChart.update();
},
error: function(data){
console.log(data);
}
});
}
updateChart();
Echo.channel('events')
.listen('RealTimeMessage', (e) => {
updateChart();
});
Event:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class RealTimeMessage implements ShouldBroadcast
{
use SerializesModels;
public string $message;
public function __construct(string $message)
{
$this->message = $message;
}
public function broadcastOn(): Channel
{
return new Channel('events');
}
}
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Data;
Use App\Events\RealTimeMessage;
class ChartController extends Controller
{
public function index() {
$infos = Data::latest()->take(30)->get()->sortBy('id');
$labels = $infos->pluck('id');
$data = $infos->pluck('data');
// dd($labels);
// return view('welcome', compact('labels', 'data'));
return response()->json(compact('labels', 'data'));
}
public function add(Request $request) {
return view('add');
}
public function store(Request $request) {
Data::create($request->data);
event(new RealTimeMessage('Done!'));
return view('add');
}
}
Change the event like so: (all public properties will be broadcasted)
public string $message;
public array $data
public function __construct(string $message, array $data)
{
$this->message = $message;
$this->data = $data;
}
Then in your controller:
...
event(new RealTimeMessage('Done!', $data));
....
I am trying to add a Vue form component to my Laravel application so I can reuse it in a few places throughout the app. But when I submit the form I get a 422 error saying that the route is not found.
Form component:
<template>
<form #submit.prevent="mail" method="POST">
</form>
</template>
<script>
import FormMixin from '../FormMixin';
export default {
mixins: [ FormMixin ],
data() {
return {
'action': 'submit',
}
}
}
</script>
Form Mixin
export default {
data() {
return {
fields: {},
errors: {},
success: false,
loaded: true,
action: '',
}
},
methods: {
mail() {
if (this.loaded) {
this.loaded = false;
this.success = false;
this.errors = {};
axios.post(this.action, this.fields).then(response => {
this.fields = {}; //Clear input fields.
this.loaded = true;
this.success = true;
}).catch(error => {
this.loaded = true;
if (error.response.status === 422) {
this.errors = error.response.data.errors || {};
}
});
}
},
},
}
Controller
public function mail(NewConctactRequest $contact) {
Mail::to('example#example.com')->send(new NewContact($contact));
return redirect()->route('thank you');
return response()->json(null, 200);
}
Web Routes
Route::get('/home', 'HomeController#index')->name('home');
Route::get('adventures', 'PageController#adventures')->name('adventures');
Route::get('crew', 'PageController#crew')->name('crew');
Route::get('events', 'PageController#events')->name('events');
Route::get('gallery', 'PageController#gallery')->name('gallery');
Route::get('thank_you', 'PageController#thank_you')->name('thank you');
Route::get('contact', 'ContactController#show')->name('contact');
Route::post('submit', 'ContactController#mail')->name('mail contact');
I have Axios installed already and the CSRF token is set in the head pf the document. When I use the form as just a standard form (not using Vue) it submits properly.
I'm having difficulty passing the value from my personal js to the controller and recovering it on the personal tpl page.
This module will serve to customize product after some selections and fields to fill out.
The selections pass from tabs to tabs.
The problem is that I can't get the value {$ var}
I have:
JS in root->modules->modulename->views->js->namejsfile.js
CONTROLLER in root->modules->modulename->controllers->front->controllername.php
VIEW in root->modules->modulename->views->templates->front->filename.tpl
in JS
$('#send').click(function(){
var ciao = 'cioaa';
var myUrl = prestashop.urls.base_url + 'index.php?fc=module&module=configuratore';
$.ajax({
type: 'get',
cache:false,
url: myUrl,
data: {
ajax: true,
datas:ciao,
action: 'fromAjax',
},
})
.done(function() {
console.log('Success!');
})
.fail(function() {
console.log('error');
});
});
in PHP
class ConfiguratoreTaskModuleFrontController extends ModuleFrontController
{
public function __construct()
{
parent::__construct();
}
public function init()
{
parent::init();
}
public function initContent()
{
parent::initContent();
$this->setTemplate('module:configuratore/views/templates/front/task.tpl');
}
$this->fromAjax();
}
public function fromAjax()
{
$mVar = Tools::getValue('datas');
return $this->context->smarty->assign(array('var'=>$mVar));
}
in TPL
{$var}
<?
public function fromAjax()
{
$mVar = Tools::getValue('datas');
$this->context->smarty->assign(array('var'=>$mVar));
$templateFile = 'module:configuratore/views/templates/front/task.tpl';
$html = $this->fetch($templateFile);
die($html); // pass to JS
}
in JS:
.done(function(html) {
console.log(html);
})
I am kinda stuck in broadcast routes. i setup a socket server with redis and configured it with Laravel. For public channel ,everything is working fine but when it comes to private or presence channel, it is somehow bypassing laravel broadcast routes. Can't figured out how & why.
i have attached a repo link so you guys can explore it too. Plus some quick bits are also below.
https://github.com/bilahdsid/socket-laravel/tree/socket
TestEvent.php
class TestEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets;
/**
* Create a new event instance.
*
* #return void
*/
public $data;
public function __construct()
{
$this->data = array(
'power'=> '10'
);
}
public function broadcastOn()
{
return new PrivateChannel('test-channel1');
}
public function broadcastWith()
{
return $this->data;
}
}
server.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('private-test-channel1', function(err, count) {
console.log(err);
});
redis.on('connection',function (socket,channel) {
console.log(socket+''|+channel);
});
redis.on('message', function(channel, message) {
console.log('Message Recieved: ' + message);
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
io.on('connection', function(socket){
console.log('a user connected');
});
routes/web-- for firing
Route::get('/', function () {
return view('home');
});
Route::get('fire', function () {
// this fires the event
broadcast(new App\Events\TestEvent());
return "event fired";
});
routes/channel.php -- below line doesn't work-- main issue
Broadcast::channel('private-test-channel', function ($user, $id) {
echo '1111'; exit;
return (int) $user->id === (int) $id;
});
Thanks.
As far as I can see you are defining a channel with the name: test-channel1:
public function broadcastOn()
{
return new PrivateChannel('test-channel1');
}
but in routes/channels.php:
Broadcast::channel('private-test-channel', function ($user, $id) {
Sounds like a typo!