Laravel Livewire Life hook livewire, v.2.11 updated/updating - laravel-livewire

When it try trigger to updated life hook when property is changed/updated not work
example
...
public function updatedName($name){
dd($this->name);
}
and I find this message from livewire doc.
Please note that mutating a property directly inside a Livewire component class doesn't trigger any of the updating/updated hooks.
Please. do someone can explain in detail this message from https://laravel-livewire.com/docs/2.x/lifecycle-hooks meaning and what should be done instead

The warning means that the Lifecycle Hooks are not called when you update a property inside the PHP component class.
An example usage is to catch when a user updates a property via the wire:model attribute.
class HelloWorld extends Component
{
public $foo;
public function updatedFoo($value)
{
//
}
public function mount()
{
$this->foo = "New Value";
// updatedFoo will NOT be called
}
}
<input type="text" wire:model="foo" />
<!-- Entering text into this field will cause the hook to be called -->

try this
public $name;
public function updatedName($value)
{
// if you want get value
dd($value);
// if you want change name to new value
$this->name = $value
}

Related

How to check Livewire event is completed

I have 3 components Map, Field & Section. Map is the parent component. Field & Section are child components.
There is an action called testField in Field component. Inside the test function first I want to trigger an event SaveSection on Section component and then continue other stuff.
// In field component
public function testField(): void
{
// Save section
$this->emitTo('section', 'saveSection');
Log::debug('Testing.....');
}
// In section component
public function saveSection()
{
Log::debug('saveSection+++++');
$this->emitTo('map', 'storeSection', $this->section, $this->sectionIndex);
}
// In map component
public function storeSection(array $section, int $sectionIndex)
{
Log::debug('storeSection-----');
// Store to DB
....
}
But it prints Testing..... before storeSection-----. Is there way I can wait for events to finish before continue.
Hi based on our conversation, I think you would want to go with hooking into Livewire and listening for message processed events.
The first step would be to wrap Log::debug('Testing.....'); in a function like this. The original idea came from #Prospero Livewire show loader when an event is emitted
public function testLog()
{
Log::debug('Testing.....');
}
You might want to tweak this to your satisfaction as this is just a recommendation.
Now you need to prepare your application to stack scripts in the base view right before the closing body tag. eg in app.blade.php like this
<body>
...//Whatever thats before it
#stack('scripts')
</body>
This would help you stack the custom script tag you would define in the component view.
After this you now use the Livewire hook. Do this properly to avoid DOM diffing issues as Livewire would cry tears in your developer console:
<script>
document.addEventListener('livewire:load', function () {
Livewire.hook("message.processed", (message, component) => {
if (message.updateQueue[0].payload.event === "storeSection") {
// I have not implemented it this way so try any of them
//#this is a brilliant decorator that finds the component
#this.emit('testLog') or #this.call('testLog')
}
});
})
</script>
This would show Testing....`` after storeSection``` is processed.
Please do let me know if this does not work as I might have to implement changes.

How do I pass data to a component in Laravel Livewire?

class Counter extends Component
{
public $counter = 0;
public $name;
public function mount($name)
{
$this->name = $name;
}
public function render()
{
return view('livewire.counter');
}
}
I'm trying to pass the name variable as parameter to the livewire component call like so #livewire('counter', ['name' => $name]) but receiving "Undefined variable $name" error. I have been following the livewire docs too, still same error. what could possibly be wrong? Thank you.
If $name is not defined, then it is not a property available in the blade file where you are including Livewire. Since we don't know anything about your blade file or controllers, I can't give you a direct answer. However, you should check if $name is set anywhere and if so, if it's available in your blade view. This error is not related to Livewire. If you've simply copied the docs without checking the variables, you might as well set it right away:
#livewire('counter', ['name' => 'Gilles'])

Livewire Lifecycle Hooks self update to upper

Hi is it possible to make live self update to upper form field payment?
because that works if set another field of form not the same.
public function updatingpayment($value)
{
$this->upper($value);
}
public function upper($value){
$process = strtoupper($value);
$this->payment=$process;
}
You still need to reference the field from the lifecycle method, Livewire doesn't know your intention.
public function updatedPayment($value)
{
$this->payment = strtoupper($value);
}

How to catch a form when it's submitted and forward form values to Dotmailer?

I've been asked to make a change to a Drupal 8 site (I'm not a Drupal Developer), the client would like an enquiry form linking up with Dotmailer. Within the theme I've tried to create a handler based on some information that I found online. But I don't know if it's doing anything. I've checked the logs section of Drupal and there isn't anything logged to indicate that the custom handler was actioned.
My theme is named abc-primary, and inside the theme folder I have created the file abc_primary.theme with the following contents;
<?php
use Drupal\media\Entity\Media;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_form_system_theme_settings_alter().
*/
function abc_primary_form_system_theme_settings_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
$theme_file = drupal_get_path('theme', 'abc_primary') . '/abc_primary.theme';
$build_info = $form_state->getBuildInfo();
if (!in_array($theme_file, $build_info['files'])) {
$build_info['files'][] = $theme_file;
}
$form_state->setBuildInfo($build_info);
$form['#submit'][] = 'abc_primary_form_system_theme_settings_submit';
}
function abc_primary_form_system_theme_settings_submit(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
// TODO: Extra submission logic.
// This submit handler will be called before default submit handler for this form.
\Drupal::logger('mymodule')->notice('mymodule submit ') ;
}
Is the above correct or am I doing something wrong?
Create a new module, and define following method:
function mymodule_form_node_form_alter(&$form, FormStateInterface $form_state) {
//you may want to check your form_id by
// $form['#form_id']
$form['actions']['submit']['#submit'][] = 'mymodule_node_form_submit';
}
function mymodule_node_form_submit($form, FormStateInterface $form_state) {
// get values from form_state
//log or send to desired web service
}
Hope it helps.

Drupal 8 subscribe to an event from inside block

I am currently trying to wrap my head around Drupal 8 module development best practices. All I'm trying to do is to have a simple form Demoform on a page where a user can input an email address. When the form gets submitted I'd like to dispatch an event demo_form.save. Also I need a block that then displays the user's email address within the block (let's say sidebar second). I have already implemented an EventSubscriber before as a test, so the event gets properly dispatched etc. and I also subscribed to the event (but how to get the information inside a block) Now my question: what's the best practice for this workflow:
File DemoForm.php
class DemoForm extends ConfigFormBase {
...
$event = $dispatcher->dispatch('demo_form.save', $e);
...
}
File DemoEventSubscriber.php
class DemoEventSubscriber implements EventSubscriberInterface {
static function getSubscribedEvents() {
$events['demo_form.save'][] = array('onConfigSave', 0);
return $events;
}
public function onConfigSave($event) {
...
}
}
This works and I can access the input from the form inside the DemoEventSubscriber class and do whatever I want with it.
But now I'd like to display the email address inside the block markup. How should this best be done ?
File DemoBlock.php
class DemoBlock extends BlockBase {
public function build() {
// here return markup with email address from form
}
}
How do I combine the eventsubscriber and the block markup ? Can Blockbase itself implement the EventSubscriberInterface and be independent from DemoEventSubscriber.php ? Or do I need to register a service that transmits the form data and then access the service within the block's build() function ? Or is there another way I am missing ?
Thanks for any input.
I am not sure what you need the event for, but to dispatch the event, use the code you have already displayed in your submitForm() function of the DemoForm class.
Because you are using ConfigFormBase, I assume that you want to store the submitted e-mail address in config, use code like from the config form documentation:
/**
* {#inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Retrieve the configuration
$this->config('mymodule.settings')
// Set the submitted configuration setting
->set('email', $form_state->getValue('email'))
->save();
// Assuming you have injected the dispatcher.
$event = $this->dispatcher->dispatch('demo_form.save', $e);
parent::submitForm($form, $form_state);
}
Within you block, you can then access the configuration for example with the static wrapper or inject the service Simple Configuration API
$config = \Drupal::config('mymodule.settings');
$message = $config->get('email');
Note that with this you can always set only one e-mail address. I don't know if that was your purpose. If you want to collect multiple e-mails then you should store them in the database and not in config.