JS Custom Event Triggered 2 Time - javascript

I'm going crazy trying to figure out what the heck is going on. In practice I have an angular v9 app that uses a shared.js file where I have stored some functions that I share with part of the static frontend. At some point from the angular app I start the call to the addToCart () function. This function among many actions has the task of emitting the onAddToCart event to do other UI update stuff. I have other similar calls (ex. Login) and they work fine, this one doesn't.
ANGULAR COMPONENT HTML
<button (click)="addProductToCart(product)">Add</button>
ANGULAR COMPONENT TS
declare function addToCart(request): any;
-----
addProductToCart(product: Product): void {
addToCart(product);
}
SHARED.JS
function addToCart(product) {
...
dispatchEventAddToCart(cartItem);
}
function dispatchEventAddToCart(cartItem) {
const addToCart = new CustomEvent('onAddToCart', {
detail: cartItem
});
window.dispatchEvent(addToCart);
}
(() => {
refreshCartCounter();
window.addEventListener('onAddToCart', (e) => {
refreshCartCounter();
console.log('add to cart executed'); <= I see two log always!
});
})();
ANGULAR COMPONENT TEMPLATE
<div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th scope="col">Prodotto</th>
<th scope="col">SKU</th>
<th scope="col">Descrizione</th>
<th scope="col">Categoria</th>
<th scope="col">Marca</th>
<th scope="col">Preventivo</th>
</tr>
</thead>
<tbody *ngIf="productFindResponse">
<tr *ngFor="let product of productFindResponse.products">
<td>
<figure class="media">
<img src="{{ product.image}}" class="rounded img-thumbnail img-sm" #img (error)="img.src = getDefaultImage()" alt="{{ product.sku }} - {{ product.description }}">
</figure>
</td>
<td>{{ product.sku }}</td>
<td>{{ product.description }}</td>
<td>{{ product.category.name }}</td>
<td>{{ product.brand.name }}</td>
<td>
<button type="button" class="btn btn-primary" (click)="addProductToCart(product)"> Add <i class="fas fa-cart-plus"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
What i'm doing wrong?
Im tried to set bubble = false but the result is the same..

Related

Failed: no element found using locator: with the Id I use getUserById

This is my code in my HTML:
<h1>User list</h1>
<button class="btn btn-primary" [routerLink]="'/register'">Register</button>
<br>
<br>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">name</th>
<th scope="col">email</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users$ | async">
<th scope="row">{{ user._id }}</th>
<td>
<a id="getUserById" routerLink="{{ user._id }}">{{ user.name }}</a>
</td>
<td>{{ user.email }}</td>
</tr>
</tbody>
</table>
Protactor does not find my id "getUserById".
This is my test that I am tryint to run:
it('should go to user detail page', async () => {
browser.waitForAngularEnabled(false);
page.navigateTo('/users/');
await page.getById.click();
expect(browser.getCurrentUrl()).toContain('/users/');
});
I'm not intimately familiar with Protractor, but it looks like either you haven't passed the id into the function, or the api call is wrong. If you've some sort of wrapper around Protractor then:
page.getById.click();
perhaps should be
page.getById('getUserById').click();
Otherwise see docs here:
https://www.protractortest.org/#/api?view=webdriver.By.id
await page.getById.click(); therefore should be
var element = element(by.id('getUserById'))
element.click();
What I guess you are trying a protractor/selenium method for getting the id of element. the best way to do that is to use element function i.e. element(by.id('goBackButton')).
Now you can use this for clicking or any thing else.
Lemme know if it helps

I want to make a have a datepicker(calendar) to filter my database record base on timestamps (Laravel 6)

How to add a date picker for my reports data (Laravel6)
I still have no idea on where to start.
Here is my report controller(index):
public function index()
{
$reports=Report::orderBy('id', 'DESC')->paginate(10);
return view('reports.index',['reports' => $reports]);
}
Here is my index on my report.index html
<div class="table-responsive">
<table class="table align-items-center table-flush">
<thead class="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Student number</th>
<th scope="col">Transaction</th>
<th scope="col">Remarks</th>
<th scope="col">Queue number</th>
<th scope="col">Created at</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
#foreach ($reports as $report)
<tr>
<td>{{ $report->name}}</td>
<td>{{ $report->snumber}}</td>
<td>{{ $report->transaction}}</td>
<td>{{ $report->remarks}}</td>
<td>{{ $report->letter}}-{{ $report->number}}</td>
<td>{{ $report->created_at }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
<div class="card-footer py-4">
<nav class="d-flex justify-content-end" aria-label="...">
{{ $reports->links() }}
</nav>
</div>
My database table look like this:
Schema::create('reports', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('snumber');
$table->string('name');
$table->string('email');
$table->string('mobile');
$table->string('department');
$table->string('letter');
$table->integer('number');
$table->string('transaction');
$table->string('remarks')->nullable();
$table->timestamps();
$table->softDeletes();
});
Please help me. Thanks!
To filter your data first you have to put your datepicker within form tag outside of your table which contains data.
If you want to use ajax call then pass that form value which contains filter date and in same index method you can check that this call is ajax call or not.
If ajax call then override variable with filtered data.
Something like this,
$reports=Report::orderBy('id', 'DESC')->paginate(10);
if($request->ajax()){
$reports=Report::orderBy('id', 'DESC')->whereDate('created_at', today())->paginate(10);
}
return view('reports.index',['reports' => $reports]);
if you dont want to use ajax call and want to load page, then you can pass the data and check that it exist or not, something like this,
$reports=Report::orderBy('id', 'DESC')
->when(! empty(\request('filterdate')), function($q) {
return $q->whereDate('created_at', today());
})
->paginate(10);
return view('reports.index',['reports' => $reports]);
It will only filter date when filterdate is not empty.
Hope this helps :)

How to print Vue objects row by row

I have a Vue application and I am trying to display each 'object' in its own table row. However, I can only get it to display each object in one column or I can get it to a point where each element is in its own row (image below). How would I make it so '0 BTC AUD 14,745.3' is in the first row and then the next object '1 ETH AUD 312.14' is displayed in the second row. I am new to Vue and was wondering if anyone was able to help me out
I have attached an image below as well as my current code, thank you!
<template>
<div class="main">
<div id="container" v-for="(index) in coin" :key="index">
<table class="coins">
<thead>
<tr class="header">
<th>Rank</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<td>{{ index }}</td>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from 'axios'
var limit = 20
export default {
name: 'ex',
data: () => ({
coin: []
}),
created () {
axios.get('https://min-api.cryptocompare.com/data/top/totalvolfull?limit=' + limit + '&tsym=AUD')
.then(response => {
for (var i = 0; i < limit; i++) {
this.coin.push(i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE)
// console.log(this.coin[i])
}
})
.catch(e => {
this.errors.push(e)
})
}
}
</script>
Change the way you are pushing data into your coin array, because here in every iteration you are pushing three items (an index, a coin name and a value) into the array but what you want to do is push a single item (an array or object) containing all this information. For code clarity also change the name of the coin array into coins. Something like this should work:
this.coins.push([i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE])
Then change the iteration in your template. First thing change the v-for to something like this:
<div id="container" v-for="(coin, index) in coins" :key="index">
and then when you print the content:
<tbody>
<td>{{ coin[0] }}</td>
<td>{{ coin[1] }}</td>
<td>{{ coin[2] }}</td>
</tbody>
I didn't test this, but I hope the general idea is enough to get you on the right direction.
maybe change how did you create this object
instead do that:
this.coin.push(i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE)
Do something like that
const coinObject = {
index: i,
name:response.data.Data[i].CoinInfo.Name,
price: response.data.Data[i].DISPLAY.AUD.PRICE
}
this.coin.push(coinObject);
and then you can loop like that in your template:
<div id="container" v-for="(coinItem, index) in coin" :key="index">
<table class="coins">
<thead>
<tr class="header">
<th>Rank</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<td>{{ coinItem.index }}</td>
<td>{{ coinItem.name }}</td>
<td>{{ coinItem.price }}</td>
</tbody>
</table>
</div>

Datatable in responsive mode ng-click doesn't work

I have a datatable that is populated by angulars ng-repeat. the code below is what I am using, I have only changed the headers and what is being repeated.
It all works perfectly until I test it on a mobile device and the table turns responsive, adding the little circled + sign to expand and view the data from the hidden columns. When this happens the "More Info" button simply doesn't work any more.
From what I have surmised, the information that appears when you click the little + sign is dynamically added at the time you click it, meaning the "more info" button is a duplicate of the original which is still in the hidden table column. I believe that is causing the ng-click event to not be "wired up".
Does anyone know if I'm correct and/or how to fix this?
<table id="dtTransactions" datatable="ng" class="table table-bordered dt-responsive dataTable no-footer dtr-inline collapsed">
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
<th>header 3</th>
<th>header 4</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in people">
<td>{{ person.name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.eyecolour }} }}</td>
<td>{{ person.shoesize }} }}</td>
<td align="center">
<button type="button" class="btn btn-default" ng-click="doSomething(person)">More Info</button>
</td>
</tr>
</tbody>
</table>
Here is my typescript for the controller. I'm very new to using typescript and am essentially copying what is already in this system and rejigging it for my own work:
module app.agreement {
'use strict';
class DetailController {
// some variable declared
static $inject = ['$compile', '$scope', 'data', 'app.services.AgreementService', '$mdDialog']
constructor(private $compile: ng.ICompileService,
private $scope: ng.IScope,
private data: any,
private agreementService: app.services.IAgreementService,
private mdDialog: angular.material.IDialogService) {
$('#dtTransactions').on('responsive-display', function () {
alert('asd');
//var c = $compile($('#dtTransactions').html());
//c($scope);
//$scope.$apply();
});
this.init();
}
init(): void {
// variables initialised
}
}
angular.module('app.agreement')
.controller('app.agreement.DetailController', DetailController);
}
I think you need ngTouch for mobile devices.
Your approach to achieve your functionality is wrong. You may try workaround with $index without repeating button as below.
<tr ng-repeat="person in people">
<td>{{ person.name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.eyecolour }} }}</td>
<td>{{ person.shoesize }} }}</td>
<td align="center">
<button type="button" class="btn btn-default" ng-click="doSomething($index)">More Info</button>
</td>
</tr>

Using ng-switch to populate a table

I'm using a Angular.js on the front end to populate a table. I want to use ng-switch to display only data that has specific data in one column, for example only show ‘week 1’ data from a list of a NFL schedule, where one column in the data is Weeks.
So right now this code doesn't show anything in the table. If anyone could help explain this it would be greatly appreciated. Maybe I should be using ng-if ? Maybe I should have a button to press to show week 1, week 2 etc.. What's the best solution for this type of situation?
Here's the controller..
// #########################
// Predictions Controller
// #########################
BLV_app.controller('PredictionsController', function($scope, PredictionsFactory, $routeParams) {
PredictionsFactory.getPredictions(function(data) {
$scope.predictions = data;
});
});
Here's the factory..
// ---------------------------
// Prediction Factory
// ---------------------------
BLV_app.factory('PredictionsFactory', function($http) {
var factory = {};
var predictions = [];
factory.getPredictions = function(callback) {
$http.get('/predictions').success(function(output) {
predictions = output;
console.log("prediction factory", predictions);
callback(output);
});
};
return factory;
});
Here's the html..
<table class="table-striped" id="table-style">
<thead id="table-header">
<tr>
<th class="text-center">HomeTeam</th>
<th class="text-center">AwayTeam</th>
<th class="text-center">Prediction</th>
<th class="text-center">Result</th>
</tr>
</thead>
<tbody ng-repeat="predict in predictions" >
<div ng-model="predict.Week"></div>
<tr ng-switch="predict.Week">
<div ng-switch-when="1">
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.HomeTeam }}</td>
<td ng-if="$even">{{ predict.HomeTeam }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.AwayTeam }}</td>
<td ng-if="$even">{{ predict.AwayTeam }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.Prediction }}</td>
<td ng-if="$even">{{ predict.Prediction }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ predict.Result }}</td>
<td ng-if="$even">{{ predict.Result }}</td>
</div>
</tr>
</tbody>
</table>
I believe there is something wrong with ng-repeat and ng-switch when binding to elements like tbody and td. Replace them with div and li makes it working properly: JSFiddle.
<div ng-repeat="predict in predictions">
<div ng-model="predict.id"></div>
<div ng-switch="predict.id">
<div ng-switch-when="1">
<li ng-if="$odd" style="background-color:#f1f1f1">{{ predict.name }}</li>
......
Changing from <div ng-repeat="predict in predictions"> to <tbody ng-repeat="predict in predictions"> makes it not working: JSFiddle.
In ng-repeat docs and ng-switch docs, it says:
Usage
as attribute:
<ANY
ng-repeat="">
...
</ANY>
But obviously they cannot be used on ANY elements.

Categories