Not displaying the content while broadcasting with pusher in Laravel - laravel

I am developing a live chat app with Laravel 7 and Pusher as broadcast driver.
And i am facing a weird problem because its broadcasting an empty object,
but in my console I am receiving the right object/comment.
indexComponent.vue:
<template>
<div>
<h1>All Comments</h1>
<div style="margin-bottom:20px;">
<textarea class="form-control" rows="3" name="body" placeholder="write a comment" v-model="commentBox" ></textarea>
<button class="btn btn-success" style="margin-top:10px" v-on:click="createComment()" >Save Comment</button>
</div>
<div v-for='comment in this.listOfComments' v-bind:key="comment.id" class='card card-body mb-2'>
<p>{{comment.body}}</p>
</div>
</div>
</template>
<script>
export default {
props: ['comments'],
data() {
return {
commentBox: '',
listOfComments: this.comments,
}
},
created: function() {
this.listen();
},
methods: {
createComment: function() {
axios.post('/api/comment', {
body: this.commentBox,
title: 'from axios',
user_id: '1'
})
.then(response => {
this.listOfComments.unshift(response.data)
this.commentBox = '';
})
.catch(error => {
console.log(error.response);
});
},
listen: function() {
Echo.channel('commentsChannel')
.listen('NewComment', (cmn) => {
console.log(cmn);
this.listOfComments.unshift(cmn);
console.log(this.comments[0]);
})
}
},
}
</script>
NewComment.php (event)
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; //for no queueing
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Comment;
class NewComment implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $comment;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(Comment $comment)
{
$this->comment = $comment;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('commentsChannel');
}
}
CommentController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Comment;
use Auth;
use App\Events\NewComment;
class CommentsController extends Controller {
public function index() {
$comments = Comment::orderBy('created_at','desc')->get();
return view('comments/index')->with('comments',$comments);
}
public function store(Request $request) {
$comment = new Comment;
$comment->body = $request->body;
$comment->title = $request->title;
$comment->user_id = $request->user_id;
if($comment->save()){
// event(new NewComment($comment));
broadcast(new NewComment($comment))->toOthers();
return $comment->toJson();
}
}
}
Please note that wen i submit a new comment the event is happening, a new division have been created, but its empty.
Anyone can help with this problem ?! Thank you in advance

Related

Laravel Job not queued?

I'm new in Laravel and i want to import a Csv file and store the data in DB with Maatwebsite\Excel. I'm trying to achieve that using jobs in laravel. When i run php artisan queue:work i don't see the job in the queue.
I've set my routes :
Route::get('/import', 'UserImportController#getImport')->name('import');
Route::post('/import_process', 'UserImportController#fileImport')->name('import_process');
I have my controller like this :
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\CsvImportRequest;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use App\Imports\UsersImport;
class UserImportController extends Controller
{
public function getImport()
{
return view('import');
}
public function fileImport(Request $request)
{
$request->validate([
'import_file' => 'required',
]);
Excel::import(new UsersImport, request()->file('import_file'));
return back()->withStatus('Import done!');
}
}
I've configured my .env like this:
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=database
SESSION_DRIVER=file
SESSION_LIFETIME=120
I've created a Job:
<?php
namespace App\Jobs;
use App\Imports\UsersImport;
use Illuminate\Bus\Queueable;
use Illuminate\Bus\Batchable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Maatwebsite\Excel\Facades\Excel;
class ImportJob implements ShouldQueue
{
use Batchable, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $uploadFile;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($uploadFile)
{
$this->uploadFile = $uploadFile;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
Excel::import(new UsersImport, $this->uploadFile);
}
}
I created a Livewire component and view:
<?php
namespace App\Http\Livewire;
use App\Jobs\ImportJob;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Storage;
class Import extends Component
{
use WithFileUploads;
public $batchId;
public $importFile;
public $importing = false;
public $importFilePath;
public $importFinished = false;
public function import()
{
$this->validate([
'importFile' => 'required',
]);
$this->importing = true;
$this->importFilePath = $this->importFile->store('imports');
$batch = Bus::batch([
new ImportJob($this->importFilePath),
])->dispatch();
$this->batchId = $batch->id;
}
public function getImportBatchProperty()
{
if (!$this->batchId) {
return null;
}
return Bus::findBatch($this->batchId);
}
public function updateImportProgress()
{
$this->importFinished = $this->importBatch->finished();
if ($this->importFinished) {
Storage::delete($this->importFilePath);
$this->importing = false;
}
}
public function render()
{
return view('livewire.import');
}
}
<div>
<form wire:submit.prevent="import" enctype="multipart/form-data">
#csrf
<input type="file" wire:model="importFile" class="#error('import_file') is-invalid #enderror">
<button class="btn btn-outline-secondary">Import</button>
#error('import_file')
<span class="invalid-feedback" role="alert">{{ $message }}</span>
#enderror
</form>
#if($importing && !$importFinished)
<div wire:poll="updateImportProgress">Importing...please wait.</div>
#endif
#if($importFinished)
Finished importing.
#endif
</div>
But when i click on import button nothing happens the import function isn't called and the job is not queued. I don't know what the issue ?

Download xlsx file without Headers, Vuejs

I have a download action, that it works, but in my .xlsx file I don't have the header, and I am not sure how can I get them. I'm using Vuejs / Axios with Laravel.
<a type="button" class="mr-3" href="/json/persons/export" download="file.xlsx">
<button #click="exportCSV" class="btn btn-primary">
Export CSV
</button>
</a>
exportCSV() {
axios
.get("/json/persons/export", {
params: {
sort_by: this.sortBy,
sort_direction: this.sortDesc
}
})
.then(response => {
//
})
.catch(error => {
//
});
},
Export Class Code
namespace App\Exports;
use App\ViewData;
use Maatwebsite\Excel\Concerns\FromCollection;
use Excel;
class DataExport implements FromCollection
{
public function collection()
{
return ViewData::all();
}
}
Well you can actually do something like
namespace App\Exports;
use App\ViewData;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Excel;
class DataExport implements FromCollection, WithHeadings
{
public function collection()
{
return ViewData::all();
}
//Define your desired headings this way, it's just for an example
public function headings(): array
{
return [
'Name',
'Surname',
'Email',
'Twitter',
];
}
}

Why broadcasting channel public not working? Laravel

I use laravel 5.3
I make routes/channels.php like this :
<?php
Broadcast::channel('messages', function() {
return true;
});
If I input the data cart and click submit, it will run this :
this.$http.post(window.BaseUrl + '/guest/add-notification', {cart_data: JSON.stringify(data)});
It will call function on the controller
The function like this :
public function addNotification(Request $request){
$input = $request->only('cart_data');
$data = json_decode($input['cart_data'], true);
event(new CartNotificationEvent($data));
}
Then it will call event
The event like this :
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class CartNotificationEvent
{
use InteractsWithSockets, SerializesModels;
public $data;
public function __construct($data)
{
$this->data = $data;
}
public function broadcastWith()
{
return [
'message' => $this->data,
];
}
public function broadcastAs()
{
return 'newMessage';
}
public function broadcastOn()
{
return new Channel('messages');
}
}
On the client, I do like this :
Echo.channel('messages')
.listen('.newMessage', (message) => {
console.log('test')
console.log(message);
});
When all the code is executed, I check on the console, the console.log not display
Why is it not working?
If I see the whole code that I make, it seems the process is correct
class CartNotificationEvent implements ShouldBroadcast is missing.

Passing data to email view Laravel 5.3

I have this scenario in my app where I have to send user's password and username to their email right away after their account created by admin. Here is what I've done so far :
Controller :
public function store(Request $request) {
$data = $request->all();
$validasi = Validator::make($data, [
'name' => 'required|max:255',
'username' => 'required|max:255|unique:users',
'email' => 'required|email|max:150|unique:users',
'password' => 'required|confirmed|min:6',
'level' => 'required|in:admin,author',
]);
if ($validasi->fails()) {
return redirect('user/create')->withInput()->withErrors($validasi);
}
$data['password'] = bcrypt($data['password']);
$email = $data['email'];
Mail::to($email)->send(new UserAdded());
User::create($data);
return redirect('user');
}
The email will send successfully but I want to pass $data['username'] and $data['password'] to email view as well.
email view :
<div class="row">
<div class="col-sm-12 col-xs-12">
<h2><span>Welcome new User!</span></h2>
<p>Your username </p>
<p>Your password</p>
</div>
Mailable function :
class UserAdded extends Mailable
{
use Queueable, SerializesModels;
public function __construct()
{
}
public function build()
{
return $this->view('email/newuser');
}
}
How to do it ? where will I define the $user data ? thanks for the help!
First of all, you need a class that builds the view. There you can define properties which you'll pass to the class. They'll be accessable in the view then.
<?php
namespace App\Mail;
use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class UserAdded extends Mailable
{
use Queueable, SerializesModels;
public $username;
public $password;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($username, $password)
{
$this->username = $username;
$this->password = $password;
}
public function build()
{
return $this->view('reference.your.view.path.here'); //CHANGE
}
}
You can now access the variables in your view.
<div class="row">
<div class="col-sm-12 col-xs-12">
<h2><span>Welcome new User!</span></h2>
<p>Your username: {{$username}} </p>
<p>Your password: {{$password}} </p>
</div>
Calling your view can be realized like this:
Mail::to($email)->send(new UserAdded($data['username'],$password));

FatalErrorException in Articles.php line 22: Call to undefined method Carbon\Carbon::createFormFormat()

I am getting error on this code so I start it from blade, then controller then modle kindly give me solution why this problem happened.
blade:
#extends ('lay')
#section('content')
<h1>Write a New Article</h1>
<hr>
{!!Form::open(['url'=>'articles'])!!}
<div class="form-group">
{!!Form::label('title','Title:')!!}
{!!Form::text('title','',['class'=>'form-control'])!!}
</div>
<div class="form-group">
{!!Form::label('body','Body:')!!}
{!!Form::textarea('body','',['class'=>'form-control'])!!}
</div>
<div class="form-group">
{!!Form::label('published_at','Published on:')!!}
{!!Form::input('date','published_at',date('Y-m-d'),['class'=>'form-control'])!!}
</div>
<div class="form-group">
{!!Form::submit('Add Article',['class'=>'btn btn-primary form-control','name'=>'submit'])!!}
</div>
{!!Form::close()!!}
#stop
controller: this is my controller of the program all this is made in laravel
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Articles;
use Request;
use Carbon\Carbon;
class ArticlesController extends Controller {
public function index()
{
/*$art=[
'title'=>'ashwani',
'body'=>'rathi',
'published_at'=>'Carbon\Carbon::now()'
];
Articles::create($art);*/
$articles=Articles::latest()->get();
return view('articles.index', compact('articles'));
}
public function show($id)
{
$article=Articles::findorFail($id);
return view('articles.show',compact('article'));
}
public function create(){
return view('articles.create');
}
public function store()
{
//$input=Request::all();
//$input['published_at']=Carbon::now();
//Articles::create($input);
Articles::create(Request::all());
return redirect('articles');
}
}
model: this is model where i using date and its not working
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
class Articles extends Model {
protected $fillable= [ 'title', 'body', 'published_at' ];
public function setPublishedAtAttribute($date)
{
$this->attributes['published_at'] = Carbon::createFormFormat('Y-m-d|', $date);
}
}
It looks like this is stemming from a small typo.
You have put createFormFormat, where you have spelt Form instead of From.
You just need to correct this in your function:
public function setPublishedAtAttribute($date)
{
$this->attributes['published_at'] = Carbon::createFromFormat('Y-m-d', $date);
}
You can use
public function getPublishedAtAttribute($date){
return Carbon::parse($date)->format('Y-m-d');
}
public function setPublishedAtAttribute($date){
$this->attributes['published_at'] = Carbon::parse($date);
}
in place of
public function setPublishedAtAttribute($date){
//$this->attributes['published_at'] = Carbon::createFormFormat('Y-m-d', $date);
return $this->attributes['published_at']->format('Y-m-d');
}

Resources