Gabotronix

Gabotronix

Member Since 11 Months Ago

Experience Points 17,480
Experience Level 4

2,520 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed 45
Lessons
Completed
Best Reply Awards 0
Best Reply
Awards
  • Start Your Engines Achievement

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • First Thousand Achievement

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • One Year Member Achievement

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • Two Year Member Achievement

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • Three Year Member Achievement

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • Four Year Member Achievement

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • Five Year Member Achievement

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • School In Session Achievement

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • Welcome To The Community Achievement

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • Full Time Learner Achievement

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • Pay It Forward Achievement

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • Subscriber Achievement

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • Lifer Achievement

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • Laracasts Evangelist Achievement

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • Chatty Cathy Achievement

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • Laracasts Veteran Achievement

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • Ten Thousand Strong Achievement

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • Laracasts Master Achievement

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • Laracasts Tutor Achievement

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • Laracasts Sensei Achievement

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • Top 50 Achievement

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

24 Mar
1 day ago

Gabotronix started a new conversation Tools For Monitoring Web Apps In Production [linux]

Hi everybody, I have a DigitalOcean VPS with a LEMP stack where I host two laravel apps, I want to know about tools for monitoring the traffic and resource comsumption of my laravel apps, maybe some tool with a web nterface or access via command line (SSH), please help a rookie out.

Thanks in advance.

Gabotronix started a new conversation Vue: Removing First Element From Array And Iterating Over It

Hi everybody, I have an array of objects called orders, for each order I iterate I want to pick the first element and also remove the first and iterate over the rest, for this purpose I created two method which take the orders array as parameter, however I'm getting weird results, I'm getting the first element two times as you can see in the image:

https://i.imgur.com/7huxhmR.png

This is my full component (notice my two methods onlyFirst and receiptExceptFirst):

<template>
<div style="width:100%; height:auto; display:flex; flex-direction:column; margin:40px 0px;">
    <div v-for="order in user.orders" :key="order.id" style="width:100%; height:auto; border:30px solid rgb(10,10,10); display:flex; flex-direction:column; margin:20px 0px; background-color:rgb(235,235,235); padding:20px;">
        <div style="width:100%; height:auto; display:flex; flex-direction:column;">
            <div style="outline:1px solid red; width:100%; height:150px; display:flex; padding:20px; align-items:center; justify-content:space-between;">
                <div style="width:50%; height:100%; display:flex; align-items:center;">
                    <div style="width:200px; height:100%; background-image:url('/img/misc/default.jpg'); background-size:cover; background-position:center;  margin:0px 20px 0px 0px;"></div>
                    <span style="font-size:17px; color:black; margin:0px 0px;">{{ onlyFirst(order.receipt).title }}</span> 
                </div>
                <span style="font-size:17px; color:black;">Código: {{ onlyFirst(order.receipt).unicode }}</span>
                    <span style="font-size:17px; color:black;">Precio: {{ onlyFirst(order.receipt).price }} €</span>
            </div>
            <div v-for="(items, index) of receiptExceptFirst(order.receipt)" :key="index" style="width:100%; height:150px; display:flex; padding:20px; align-items:center; justify-content:space-between;">
                <div style="width:50%; height:100%; display:flex; align-items:center;">
                    <div style="width:200px; height:100%; background-image:url('/img/misc/default.jpg'); background-size:cover; background-position:center;  margin:0px 20px 0px 0px;"></div>
                    <span style="font-size:17px; color:black; margin:0px 0px;">{{ items.title }}</span> 
                </div>
                <span style="font-size:17px; color:black;">Código: {{ items.unicode }}</span>
                    <span style="font-size:17px; color:black;">Precio: {{ items.price }} €</span>
            </div>
            <button style="width:auto; height:auto; margin:0px 0px 0px auto; display:flex; align-items:center;" type="button">
                <span style="font-size:17px; color:var(--web_primary_color); margin-left:auto;">mostrar todo</span>
                <i class="fas fa-sort-down" style="font-size:20px; color:var(--web_primary_color); margin:0px 5px;"></i>
            </button>
            <div style="width:100%; height:1px ; border-bottom:2px solid rgb(56,56,56); margin:10px 0px;"></div>
            <div style="width:100%; height:auto; display:flex; align-items:center;">
                <span style="font-size:15px; color:rgba(0,0,0,0.9);">Canjeado el 23/4/2018 a las 14:00</span>
                <span style="font-size:20px; color:rgba(0,0,0,0.9); margin-left:auto;">Total:</span>
                <span style="font-size:20px; color:rgba(0,0,0,0.9);">{{ order.cartTotalPrice }} €</span>
            </div>
        </div>
    </div>
</div>
</template>
<!--SCRIPTS-->
<script>
import { mapState, mapActions } from 'vuex';
export default{
name: 'ORDERList1',


props: {
    user: {required:true }
},


mounted () {
    console.log(this.$options.name+' component successfully mounted');
},


methods:{

    
    onlyFirst: function(receipt){
        let onlyFirst = receipt[0];
        return onlyFirst;
    },

    
    receiptExceptFirst: function(receipt){
        let receiptExceptFirst = receipt.splice(0, 1);
        console.log(receiptExceptFirst);
        return receiptExceptFirst;
    }
    
    
}


}
</script>

What am I doing wrong??

23 Mar
2 days ago

Gabotronix started a new conversation Setting Up Proper Permissions For Laravel App In Ubuntu

Hi everybody, I have a DigitalOcean VPS with ubuntu, I'm fairly new to web apps deployng and I'd like some advice on what would be the best way to properly set permissions on my laravel app folder so I don't have to worry about getting permissions errors. I know about storage and cache folders and how I should give www-data read and write permissions but is there an easy way to set up all this nicely so I don't have to be changing permissions each time a new folder, file is added?

What does yur initial setup looks like after say, cloning a git repository into the /var/www folder?

Thanks in advance and I'm open to all advice.

19 Mar
6 days ago

Gabotronix started a new conversation Issue Trying To Calculate Average With Javascript Method

Hi everybody, I'm trying to calculate average score from an array of objects, for some reason I'm getting the following error:

[Vue warn]: Error in render: "TypeError: discountReviews[i] is undefined"

I'm using a simple for in my method to calculate average:

getAverage: function(discount){


        let discountReviews = discount.discountreviews;

        if(discountReviews.length == 0){
            return 5;
        }
        else{
            let total = 0;
            console.log(discountReviews.length);
            for(var i=0; i<= discountReviews.length; i++){
                total = parseInt(total) + parseInt( discountReviews[i].rating);
            }

            let average = Math.ceil(total / discountReviews.length);
        
            return average;

        }

    },

My discountreviews array looks like this:

https://i.imgur.com/xekDWCw.png

Gabotronix started a new conversation Call To A Member Function SetCookie() On Null On Laravel Middleware

Hi everybody, I made a custom route middleware to check if my user has enough privileges to see a page, when user doesn't have enough privileges I get the following error message:

 Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR)
Call to a member function setCookie() on null

This is my controller:

<?php
namespace App\Http\Middleware;


use Closure;
use Illuminate\Http\Request;
use Auth;



class AuthAdmin
{


    public function handle($request, Closure $next)
    {
        $user = Auth::user();

        if($user && $user['privileges'] > 2){
            return $next($request);   
        }

        return view('auth.login');
        
    }
}

Any idea what's wrong with my code?

18 Mar
1 week ago

Gabotronix started a new conversation Issue Sorting By Date With Lodash

Hi everybody, I'm trying to have a sorted list of items by data using lodash and vue moments, I'm using a computed property but for some reason this computed property named sortByUsedDate returns a number instead of a sorted array... it's returning 11 exactly.

This is my code:

sortByUsedDate: function(){

        let sortedCodes = _.orderBy(this.modalPayload.discountcodes, (code) => {
            return Vue.moment(code.usedDate).format('MDYYYY');
        }, ['desc']);

        let sortedWithoutUnused = _.remove(sortedCodes, function(code) {
            return code.isBought === 1;
        });

        let unusedCodes = _.filter(this.modalPayload.discountcodes, function(code){
            return code.isBought == 0;
        });

        let final = sortedWithoutUnused.push(unusedCodes);

        return final;
    }
16 Mar
1 week ago

Gabotronix started a new conversation Getting 500 Error After Deploying My Laravel App

Hi everybody, I'm getting 500 erro after deploying my web app, I get the following error:

#1 /var/www/gabrielgb.es/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php(122): file_put_contents('/var/www/gabrie...', '<?php $__env->s...', 0)
#2 /var/www/gabrielgb.es/vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php(122): Illuminate\Filesystem\Filesystem->put('/var/www/gabrie...', '<?php $__env->s...')
#3 /var/www/gabrielgb.es/vendor/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php(51): Illuminate\View\Compilers\BladeCompiler->compile('/var/www/gabrie...')
#4 /var/www/gabrielgb.es/vendor/larave...
PHP message: PHP Fatal error:  Uncaught ErrorException: file_put_contents(/var/www/gabrielgb.es/storage/framework/views/19e7e3b2e87a6fea9c23327a9ff41e59e6f424c9.php): failed to open stream: Permission denied in /var/www/gabrielgb.es/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:122
Stack trace:
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'file_put_conten...', '/var/www/gabrie...', 122, Array)
#1 /var/www/gabrielgb.es/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php(122): file_put_contents('/var/www/gabrie...', '<?php $__env->s...', 0)
#2 /var/www/gabrielgb.es/vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php(122): Illuminate\Filesystem\Filesystem->put('/var/www/gabrie...', '<?php $__env->s...')
#3 /var/www/gabrielgb.es/vendor/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php(51): Illuminate\View\Compilers\BladeCompiler->co

afaik this is a permissions issue but I don't get why I'm getting this since I gave 775 permissions to bootstrap and sorage folders as you can see here:

https://i.imgur.com/grxzO0B.png

I'm using a digitalocean VPS and nginx as web server. What am I doing wrong??

13 Mar
1 week ago

Gabotronix started a new conversation Issue With Git Pull On My Server

Hi everybody, I'm trying to get the grasp of git but having some diffculties, what I do is have a project with two branches. one is master and the other is develop, I do my day to day coding in develop and after I feel my code is safe.

I checkout to master and merge master with develop. Apparently when I do git merge develop it tells me I fitst need to commit some changes, is this normal? shouldn't it automatically merge the changes into master?

And my other question, I have a vps where I'm testing production enviroment for learning, I cloned a git repository there and my site is live, noe I used php artisan down in order to update my production site with the changes added to the remote repository, I used git pull origin master to do so but now I get this message:

https://i.imgur.com/ufN4pBu.png

how can I fix this, I want to bring the changes from remote to my live server but I can't...

I'm a noob with git but I feel like it'll come in handy in the futur so please help me out.

Gabotronix started a new conversation SSL Securing For My Laravel App With Let's Encrypt

Hi everybody, I have a site which I want to have HTTPS for, this is my first time doing something like this so bear with me.

I have a VPS with ubuntu and nginx as web server, I have followed this steps:

1- sudo add-apt-repository ppa:certbot/certbot

2 - sudo apt install python-certbot-nginx

3 - sudo ufw allow 'Nginx Full' sudo ufw delete allow 'Nginx HTTP'

And I also have my dns set up and ready, let's say example.com ...

Now what command should I use?

I have seen like this:

sudo certbot --nginx -d tudominio.com -d www.tudominio.com

but also like this:

sudo certbot certonly --webroot --webroot-path=/var/www/html/quickstart -d example.com -d www.example.com

I also have another question, in ubuntu I create symbolic link to enable my sites, but how can I take down indifinitely a site? should I do php artisan down or should I remove the sym link, adn hw do I do this?

which one should I use?

12 Mar
1 week ago

Gabotronix started a new conversation Vue: Accessing Specific Item Inside Array Of Objects

Hi everybody, I made a vue component for my error views, the component receives an http status code from laravel's error handler, then with that code and checking against my errorInfo array I want to show the proper error message, however I'm getting the following error message:

TypeError: "this.errorInfo.code is undefined"

This is my full component:

<template>
<div class="LAYOUTerror1_maincontainer">
    <div class="LAYOUTerror1_container">
        <span class="LAYOUTerror1_code" v-text="code"></span>
        <div class="LAYOUTerror1_divider"></div>
        <div class="LAYOUTerror1_description" v-text="errorMessage"></div>
        <a class="LAYOUTerror1_link_container" href="/">
            <span class="LAYOUTerror1_link_description">Volver a inicio</span>
        </a>
    </div>
</div>
</template>
<!--SCRIPTS-->
<script>
import { mapState, mapActions } from 'vuex';
export default {
name: 'LAYOUTerror1',


computed:{
    errorMessage: function(){
        return this.errorInfo.code[this.code].message;
    },
},


data() {
    return {
        errorInfo: [
            { code: 404, message: 'Oops, parece que algo salío mal! Intentelo más tarde.' },
            { code: 503, message: 'Estamos de mantenimiento, disculpe las molestias.' },
            
        ]
    }
},


props: {
    code: { required:true }
},


mounted() {
    console.log(this.$options.name + ' component succesfully mounted');
},


}
</script>
<!--STYLES-->
<style scoped>
.LAYOUTerror1_maincontainer{width:100%; height:100vh; position:fixed; top:0px; left:0px; z-index:99999999999999; background-color:white; display:flex; flex-direction:column; justify-content:center; align-items:center;}
.LAYOUTerror1_container{width:60%; height:auto; display:flex; flex-direction:column;}
.LAYOUTerror1_code{font-size:200px; color:rgba(0,0,0,0.7);}
.LAYOUTerror1_divider{width:100px; height:1px; border-bottom:5px solid rgba(0,0,0,0.3);}
.LAYOUTerror1_description{font-size:20px; color:rgba(0,0,0,0.9); width:50%; margin:20px 0px 20px 0px;}
.LAYOUTerror1_link_container{align-self:flex-start; display:flex; align-items:center; justify-content:center; margin:20px 0px 20px 10px; padding:10px 10px; border-radius:4px; border:1px solid rgba(0,0,0,0.4); box-shadow:2px 2px 4px rgba(0,0,0,0.3);}
.LAYOUTerror1_link_description{color:rgba(0,0,0,0.7); font-size:18px; font-weight:600;}
</style>

What am I dong wrong?

10 Mar
2 weeks ago

Gabotronix started a new conversation Nginx Logs Per Webapp?

Hi everybody, I'm using nginx as a webserver and I want to deploy a laravel app in my vps, I want to have nginx dump error and access logs in their respective files, that is so each server block (web) has its own logs, I think this wwould be the best for managing the logs and debugging.

So this may seem like a noob question but how do I create log files on my ubuntu enviroment, should I just:

sudo nano /etc/nginx/logs/app1-access.log
09 Mar
2 weeks ago

Gabotronix left a reply on Question About Git Workflow

@EJDELMONICO - I develop alone, your idea sounds good too!

Gabotronix started a new conversation Question About Git Workflow

Hi everybody, I'm trying to bring myself to use git to develop my web apps, I was wondering if this workflow would be a good start for me. Basically I have the master branch, this would be also called production branch were only safe and working code resides, then I could have a develop branch, on this branch I could be adding new features, fixes branches nad I guess this new branches off develp could be merged with master? or maybe merged with develop and back to master? what would be the best solution?

I'm open to suggestions of all kinds.

07 Mar
2 weeks ago

Gabotronix started a new conversation Jquery Adding Sticky Class When Scrolled Past Element

Hi everybody, I have an element inside my vue component I want to apply a fixed class when the user scrolls past it, however it's not taking effect, and I can see the sticky console.log is firing every scroll instead of only when the element is passed.

Here is my component with jquery code.

<template>
<div id="sticky" style="width:35%; height:85vh; padding:0px 0px; margin:0px 0px 0px auto; background-color:rgb(10,10,10); display:flex; flex-direction:column; position:relative; border:5px solid #9d0000; overflow:hidden; outline:2px solid red;">
        </div>
    </div>
</template>
<!--SCRIPTS-->
<script>
import $ from 'jquery';
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex';
export default {
name: 'CARTmodal2',


computed: {
    ...mapState('Cart', ['showCartTab', 'cartItems']),
    ...mapGetters('Cart', ['cartTotalPrice']),

},


mounted() {
    console.log(this.$options.name+' component successfully mounted');

    let sticky = $('#sticky'),
    stickyTop = sticky.offset().top,
    scrolled = false,
    $window = $(window);

    /* Bind the scroll Event */
    $window.on('scroll', function(e) {
        scrolled = true;
    });

    let timeout = setInterval(function() {
        /* If the page was scrolled, handle the scroll */
        if (scrolled) {
            scrolled = false;
            if ($window.scrollTop() >= stickyTop) {
                sticky.addClass('fixed');
                console.log("sticky");
            }
            else {
            sticky.removeClass('fixed');
            }
        }
    }, 200);


},



};
</script>
<style scoped>
.fixed{position:fixed; top:0px; left:0px; border:1px slid black;}
</style>

Any idea what am I doing wrong?

05 Mar
2 weeks ago

Gabotronix started a new conversation Vue: Apply Css Class If Product Is In Cart

Hi everybody, I'm trying to make a shopping cart with laravel + vue, the main issue here is on vue's part.

In my cart component you can add/remove products with a simple click, if a product is added to the cart I want to apply a css to the product card.

I created a computed property for this and added a class binding to the product card node but I'm getting the following error:

[Vue warn]: Error in render: "TypeError: _vm.isAlreadyAdded is not a function"

found in

---> <PRODUCTlchoice1> at resources/js/components/products/PRODUCTchoice1.vue

Here is my component:

<template>
<div style="width:100%; height:auto; display:flex; flex-direction:column;">
        <div style="width:100%; height:auto; display:flex; flex-wrap:wrap; padding:10px;">
            <div :class="{ 'selected_product' : isAlreadyAdded(product.id) }" class="product" v-for="product in productcategory.products" :key="product.id" @click.self="selectProduct(product, $event)" style="width:31%; height:60px; border:0px solid black; background-color:rgb(235,235,235); margin:10px 10px; display:flex; align-items:center; padding:0px 5px 0px 20px; cursor:pointer;">
                <span style="font-size:20px; color:rgba(0,0,0,0.9);">{{ product.title }}</span>
                <div class="add_button" style="width:40px; height:40px; border-radius:2px; display:flex; align-items:center; justify-content:center; margin:0px 0px 0px auto; background-color:rgb(135, 229, 81);">
                    <i class="fa fa-plus" style="font-size:25px; color:white;"></i>
                </div>
            </div>
        </div>
    </div>
</div>
</template>
<!--SCRIPTS-->
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
name: 'PRODUCTlchoice1',


computed: {
    isAlreadyAdded: function(productId){
        return this.cartItem.find( cartItem => cartItem.id == productId);
    }

},


data() {
    return {
        cartItem: [],
        cartItems: [],
    }
},


props: {
    productcategories: { required:true }
},


mounted() {
    console.log(this.$options.name+' component successfully mounted');
},


methods:{

    selectProduct: function( product, event){

       //add or remove product logic

    },


}


};
</script>
<!--STYLES-->
<style scoped>
.product:hover{background-color:rgb(135, 229, 81) !important;}
.selected_product{background-color:var(--web_primary_color) !important; color:white; border:2px solid rgb(56,56,56);}
</style>

What's wrong with my code? should I use a computed property (this are reactive afaik?), I know I could capture the clicked event target and apply a class with css but I was adviced not to do this.

Any ideas or suggestions?

Thanks in advance!

Gabotronix left a reply on Eager Loading BelongsTo Relationship

Uhmm, this is really erird. Both methods return null.

Gabotronix left a reply on Eager Loading BelongsTo Relationship

@BASHY - Uhmm, I tired this and I'm getting productcategory: null, so I'll try appending

Gabotronix started a new conversation Eager Loading BelongsTo Relationship

Hi everybody, I have two models Product and ProductCategory which are related, one product beongs to one product category and one product category can have many products.

Here are my models:

Product:

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class Product extends Model
{
    
    
    protected $table = 'products';
    
    
    public function productcategory()
    {
        return $this->belongsTo('App\Models\ProductCategory');
    }

    
}

ProductCategory:

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class ProductCategory extends Model
{
    
    
    protected $table = 'productcategories';
    
    
    public function products()
    {
        return $this->HasMany('App\Models\Product');
    }


}

I retrieve all categories with their respective attached products like this:

$productCategories = ProductCategory::with('products')->get();

This works but I want it so that I can access product category info from the products, this is because I'm using vue to loop throught each category products but I need to access category info from product itself, not just the product_category_id but other fields!

In my component I want to do this:

product.productcategory.name

But currently I only get access to:

product.product_category_id

I'd rather not make an ajax call to my API to get this information, how can I get around this?

04 Mar
3 weeks ago

Gabotronix started a new conversation Vue: Error In Render: "TypeError: Event Is Undefined"

Hi everybody, I'm trying to gain access to the event instance of a click in my vue template, however I'm getting the following error message:

[Vue warn]: Error in render: "TypeError: event is undefined"

This is the click event I want to capture in my method:

<div v-for="product in productcategory.products" :key="product.id" :click="selectProduct(product)" style="width:100%; height:50px; outline:1px solid red; margin:5px 0px;">
                <span>{{ product.title }}</span>
            </div>

And my methods where I think the error is:

methods:{

    selectProduct: function( product, event){
        
        let productCategoryId = product.product_category_id;

        switch(productCategoryId){

            case 1: //Hamburguesa
                let hamburgerCount = this.cartItem.filter(cartItem => cartItem.productCategoryId == 1).length;
                let isAlreadyAdded = this.cartItem.filter(cartItem => cartItem.id == product.id).length;
                if(hamburgerCount < 1 && isAlreadyAdded == 0){
                    //add product to cartItem
                    this.cartItem.push({ id: product.id, title: product.title, productCategroyId: product.product_category_id, finalPrice: product.finalPrice })
                    event.target.classList.add("active");
                }
                else if(isAlreadyAdded > 0){
                    //find index and remove from array
                    event.target.classList.remove("active"); 
                }
            break;
        }
        
    }
}

Any idea how I can do this?

03 Mar
3 weeks ago

Gabotronix started a new conversation SQLSTATE[42S22]: Column Not Found: 1054 Unknown Column

Hi everybody, I'm trying to retrieve all product categories with all their respective products, one product belongs to one product category and one product category can have many products.

When I retrieve productCategories I get the following error:

 Illuminate \ Database \ QueryException (42S22)
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'products.product_category_id' in 'where clause' (SQL: select * from `products` where `products`.`product_category_id` in (1, 2, 3))

This is my migrations file for product and categories:

<?php


use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;


class ProductsAndCategories extends Migration
{
    

    public function up()
    {
        
        
        //CREATE PRODUCT CATEGORIES TABLE
        Schema::create('productcategories', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('description')->nullable();
            $table->string('image')->nullable();
            $table->timestamps();
        });
        DB::table('productcategories')->insert([
            'title' => 'Hamburguesas',
        ]);
        DB::table('productcategories')->insert([
            'title' => 'Toppins',
        ]);
        DB::table('productcategories')->insert([
            'title' => 'Salsas',
        ]);


        //  CREATE PRODUCTS TABLE
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('productcategory_id')->index();
            $table->foreign('productcategory_id')->references('id')->on('productcategories');
            $table->string('title');
            $table->string('description')->nullable();
            $table->string('body')->default('');
            $table->string('image')->nullable()->default(config('globals.dummy_image'));
            $table->boolean('isVisible')->default(true);
            $table->integer('stockLeft')->default(0);
            $table->decimal('halfPrice', 5,2)->default(0.00);
            $table->decimal('fullPrice', 5,2)->default(0.00);
            $table->decimal('finalPrice', 5,2)->default(0.00);
            $table->timestamps();
        });
        DB::table('products')->insert([
            'productcategory_id' => 1,
            'title' => 'Hamburgesa 1',
            'finalPrice' => 2.99,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 1,
            'title' => 'Hamburgesa 2',
            'finalPrice' => 2.99,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 1,
            'title' => 'Hamburgesa 3',
            'finalPrice' => 2.99,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 1,
            'title' => 'Hamburgesa 4',
            'finalPrice' => 2.99,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 2,
            'title' => 'Toppin 1',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 2,
            'title' => 'Toppin 2',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 2,
            'title' => 'Toppin 3',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 2,
            'title' => 'Toppin 4',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 2,
            'title' => 'Toppin 5',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 2,
            'title' => 'Toppin 6',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 2,
            'title' => 'Toppin 7',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 3,
            'title' => 'Salsa 1',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 3,
            'title' => 'Salsa 2',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 3,
            'title' => 'Salsa 3',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 3,
            'title' => 'Salsas 4',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 3,
            'title' => 'Salsa 5',
            'finalPrice' => 0.00,
        ]);
        DB::table('products')->insert([
            'productcategory_id' => 3,
            'title' => 'Salsa 6',
            'finalPrice' => 0.00,
        ]);


    }

    
    public function down()
    {
        Schema::dropIfExists('products');
        Schema::dropIfExists('productcategories');
    }


}

And my two related models:

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class Product extends Model
{
    
    
    protected $table = 'products';
    
    
    public function productcategory()
    {
        return $this->belongsTo('App\Models\ProductCategory', 'productcategory_id');
    }

    
}

Gabotronix started a new conversation Creating Symbolic Link For Phpmyadmin In Ubuntu

Hi everubody, I'm following a tutorial on installing phpmyadmin in my nginx web server, I download and install the needed repositories for this, in the tutorial a symbolic link is created like this:

sudo ln -s /usr/share/phpmyadmin /var/www/app-root/

And then that link is "moved" to a more secure place to avoid malicious bots:

sudo mv phpmyadmin hidden-pma

I have a few questions regarding this:

-Do I need to create a symbolic link for to each of my production apps in order to use pma in them.

-Instead of creating link and moving it can I just create a symbolic link to something like :

sudo ln -s /usr/share/phpmyadmin /var/www/app-root/pma-hidden

Thanks in advance for helping a noob out!

Gabotronix started a new conversation Syntax Highlighting For Text Confi Files In Visual Studio Code

Hi everybody, my favorite text editor is VS Code, it's simple and great but I was wondering if there's an addon for working with the various text files you can find in a production enviroment like nginx conf files, apache conf files and everything...

Any experiences?

02 Mar
3 weeks ago

Gabotronix started a new conversation Failed To Mount Component: Template Or Render Function Not Defined

Hi everybody, none of my vue components are being rendered, I'm getting the following error message in console.

This is how my app.js file looks.

window.Vue = require('vue');
Vue.config.productionTip = false;

const moment = require('moment');
require( 'moment/locale/es' );
Vue.use(require( 'vue-moment' ), { moment });

Vue.component('events-panel', require('./components/admin/events/EventsPanel.vue'));
Vue.component('events-create-modal', require('./components/admin/events/EventsCreateModal.vue'));
Vue.component('events-edit-modal', require('./components/admin/events/EventsEditModal.vue'));
Vue.component('events-edit-visible-modal', require('./components/admin/events/EventsEditVisibleModal.vue'));
Vue.component('events-delete-modal', require('./components/admin/events/EventsDeleteModal.vue'));
Vue.component('pages-panel', require('./components/admin/pages/PagesPanel.vue'));
Vue.component('pages-create-modal', require('./components/admin/pages/PagesCreateModal.vue'));
Vue.component('pages-edit-modal', require('./components/admin/pages/PagesEditModal.vue'));
Vue.component('pages-delete-modal', require('./components/admin/pages/PagesDeleteModal.vue'));
Vue.component('users-panel', require('./components/admin/users/UsersPanel.vue'));
Vue.component('users-create-modal', require('./components/admin/users/UsersCreateModal.vue'));
Vue.component('users-edit-modal', require('./components/admin/users/UsersEditModal.vue'));
Vue.component('users-delete-modal', require('./components/admin/users/UsersDeleteModal.vue'));


import store from './store';
import "./directives";
import "./filters";


const app = new Vue({

    el: '#vueapp',
    store,

    created () {
        console.info('******* VUE INSTANCE MOUNTED *******');
        console.info('Vue moment locale is: '+Vue.moment().locale()+'.')
    },

});

Any idea what I'm doing wrong, I got this message after goin from async loading components to the normal way.

Gabotronix started a new conversation Another Problem With Laravel-mix And Async Components

After I though I fixed all the issues now none of my async components are loading, I ge the following error in console:

https://i.imgur.com/ruMCU8y.png

This is my webpack.mix config file:

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */


// Override mix internal webpack output configuration
mix.config.webpackConfig.output = {
   chunkFilename: 'js/[name].bundle.js',
   publicPath: '/',
};

mix.babelConfig({plugins: ["@babel/plugin-syntax-dynamic-import"]});

mix.js('resources/js/app.js', 'public/js')
   .sass('resources/sass/app.scss', 'public/css');

My package.jon file

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
    "devDependencies": {
        "@babel/plugin-syntax-dynamic-import": "^7.2.0",
        "babel-eslint": "^8.2.6",
        "babel-plugin-dynamic-import-webpack": "^1.1.0",
        "babel-preset-env": "^1.7.0",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "laravel-mix": "^4.0.14",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.2",
        "sass": "^1.17.2",
        "sass-loader": "^7.1.0"
    },
    "dependencies": {
        "axios": "^0.18",
        "jquery": "^3.2",
        "lodash": "^4.17.4",
        "vue": "^2.6.8",
        "vue-moment": "^4.0.0",
        "vue-parallaxy": "^1.1.1",
        "vue-template-compiler": "^2.6.8",
        "vue2-datepicker": "^2.6.4",
        "vue2-editor": "^2.6.6",
        "vuex": "^3.1.0",
        "vuex-persistedstate": "^2.5.4"
    }
}

And my babelrc file:

{
    "plugins": ["@babel/plugin-syntax-dynamic-import"]
}
01 Mar
3 weeks ago

Gabotronix started a new conversation Issue With Babel Dynamic Imports And Laravel-mix

Hi everybody, when running npm run watch I get the following warning which makes compilation fail.

WARNING in ./resources/js/app.js 19:9-58
System.import() is deprecated and will be removed soon. Use import() instead.
For more info visit https://webpack.js.org/guides/code-splitting/
 @ multi ./resources/js/app.js ./resources/sass/app.scss /js/app[0]

This is my package.json file:

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
    "devDependencies": {
        "@babel/plugin-syntax-dynamic-import": "^7.2.0",
        "babel-eslint": "^8.2.6",
        "babel-plugin-dynamic-import-webpack": "^1.1.0",
        "babel-preset-env": "^1.7.0",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "laravel-mix": "^4.0.14",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.1",
        "sass": "^1.17.2",
        "sass-loader": "^7.1.0"
    },
    "dependencies": {
        "vue": "^2.6.7",
        "vue-template-compiler": "^2.6.7",
        "axios": "^0.18",
        "jquery": "^3.2",
        "lodash": "^4.17.4",
        "tomtom-sdk": "^1.0.0",
        "vue-moment": "^4.0.0",
        "vue-parallaxy": "^1.1.1",
        "vue2-datepicker": "^2.6.4",
        "vue2-editor": "^2.6.6",
        "vuex": "^3.1.0",
        "vuex-persistedstate": "^2.5.4"
    }
}

My .babelrc file which is currently inside my .vscode folder, dunno if that's the best place...

{
    "plugins": ["@babel/plugin-syntax-dynamic-import"]
}

OF COURSE if I remove System.import for import I get the following error:

https://i.imgur.com/UEhxaOh.png

which doesn't makes much sense to me since I have already added the plugins section to my babelrc file...

28 Feb
3 weeks ago

Gabotronix started a new conversation Help With Npm Warnings

Hi everybody, I'm getting the following errors when using npm install on my machine:

https://i.imgur.com/D9hGtID.png

I tried with npm audit fix but it didn't worked.

I'm kind of a newbie with npm still so any help would be great!

27 Feb
3 weeks ago

Gabotronix left a reply on Nuxt SSR + Laravel API Nginx Conf Advice

@AUDUNRU - Will look at that but I haven't used Forge ever, I'd be using DigitalOcean's LEMP stack probably.

Gabotronix started a new conversation Nuxt SSR + Laravel API Nginx Conf Advice

Hi everybody, I'm thinking about trying the following stack: bascially Laravel would act as the API backend and Nuxt would server side render the app and fetch (vuex data) for the components with axios, that way I'd have a server side rendered, SEO friendly app using both vue and laravel.

Is this a good combo, I don't want to use express or similar since I'm not experienced with nde.js yet.

Both backend and forntend would be their own projects, that is two separate folders, I think this would be the best option to manage and mantain forntend and backend separately.

Now I'll be using nginx as a web server, and I'd have something like www.example.com which would be my nuxt frontend AND www.api.example.com as my API where all my endpoints are placed (laravel).

My question is how could my nginx configuration file look like? I have read a bit and what I'm supposed to do is use nginx as a reverse proxy right? anyone have a virtusl host conf for such a setup in nginx?

Any help, advice or suggestions is greatly appreciated for a noob like me!

24 Feb
1 month ago

Gabotronix started a new conversation Git: Issue Pushing To Remote Gitlab Repository

Hi everybody, this is my first time using gitlab, I first used git init to create local repository of my laravel priject, after that I added all files and made the initial commit, after that I created a gitlab account and created an empty repository for my laravel project.

I added the remote repository adn right now I'm trying to push my project to the remote repository but I'm getting the following error message:

https://i.imgur.com/fE15y5R.png

after trying a that I tried a git pull as suggested but I got this:

https://i.imgur.com/jnRS5C6.png

I'm not able to push to remote yet...

Gabotronix started a new conversation Vue: Css Transition Not Working On Initial Render

Hi everybody, I'm trying to apply a simple vue transition when the component appears on screen, for that I'm using the appear word on the transition as seen in the docs, however my elements are not getting transitioned, why is this?

Here is my component (notice both transitions with fade-slow name):

<section class="SLIDERcontainer3_maincontainer" :style="'width:'+width+'; height:'+height+';'">
    <div class="SLIDERcontainer3_item" v-show="!showSlider">
        <transition name="fade-slow" appear>
        <div class="SLIDERcontainer3_nav_maincontainer">
            <a class="SLIDERcontainer3_nav_link" :href="link.url" v-for="link in globals.portLinks" :key="link.name">{{ link.name }}</a>
        </div>
        </transition>
        <transition name="fade-slow" appear>
        <div class="SLIDERcontainer3_texts_maincontainer">
            <div class="SLIDERcontainer3_texts_row_container">
                <span class="SLIDERcontainer3_texts_row_title_deco_left" v-text="'<'"></span>
                <span class="SLIDERcontainer3_texts_row_title">Gabriel Gabarrón </span>
                <span class="SLIDERcontainer3_texts_row_title_deco_right">></span>
            </div>
            <div class="SLIDERcontainer3_texts_row_container">
                <span class="SLIDERcontainer3_texts_row_title_2">desarrollador web full-stack</span>
                <button class="SLIDERcontainer3_texts_row_button_container" type="button" @click="toggleSlider()">
                    <span class="SLIDERcontainer3_texts_row_button_text">Play</span>
                    <i class="SLIDERcontainer3_texts_row_button_icon fas fa-play"></i>
                </button>
            </div>
        </div>
        </transition>
        <div class="SLIDERcontainer3_gradient_overlay"></div>
        <div class="SLIDERcontainer3_image move" style="background-image:url('/img/misc/portfolio-design.jpg');"></div>
    </div>
    <transition name="fade-slow">
        <component :is="activeSlider" :globals="globals" v-if="showSlider"></component>
    </transition>
</section>
</template>

And the related css classes.

.fade-slow-enter { opacity:0; }
.fade-slow-enter-active { transition: all 2s ease; }
.fade-slow-enter-to { opacity:1; }
.fade-slow-leave { opacity:1; }
.fade-slow-leave-active { transition: all 2s ease; }
.fade-slow-leave-to { opacity:0; }
20 Feb
1 month ago

Gabotronix left a reply on Issue Editing Remote Files With Winscp

@S4MUEL - Tried this but it's not working, afaik I'm already loging as sudo with winscp, I mean my current only user was added to sudo group already

Gabotronix started a new conversation Issue Editing Remote Files With Winscp

Hi everybody, I downloaded winscp to access my first vps via sftp, I also set winscp's editor to visual studio since it's my favorite one! after this I tried editing an nginx conf file remotely with visual studio, I try saving the changes BUT I get an error message and the changes are NOT saved to my remote server sadly.

I'm making the changes using sudo since apparently using root is dangerous, I disabled root login with the following command too: sudo passwd -l root

This is the error message: https://i.imgur.com/NpRfAJf.png

Obviously it has something to do with permissions but since this is my first time tinkering with ubuntu/remote server I'm not sure about what permisssions to set, I want to set the correct ones to not make my server vulnerable to attack.

Any help or advise is greatly appreciated!

19 Feb
1 month ago

Gabotronix started a new conversation Help With Ubuntu Enviroment Commands And General Tips

Hi everybody, today I got my first VPS at DigitalOcean, this is my first time tinkering with ubuntu and so far I'm linking it but I'm still a noob, for example:

cd ~
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

In the code above what is "cd ~" for, what does it accomplish?

and about curl command, I know it can download files from url but why does it have this part " | php"? what's the pipe for?

Also is there a place similar to stackoverflow where I can make this kind of questions? mainly about ubuntu server app deployments, currently I', installing the LEMP stack and getting used to use the apt-get respository commands (install, purge...) and nano editor

14 Feb
1 month ago

Gabotronix started a new conversation Is DigitalOcean's LEMP One Click App Ready To Serve A Laravel Application?

Hi everybody, I'm thinking about creating my first droplet and the LEMP one click install sounds pretty good, I was wondering if it comes with all the packages needed to run a laravel app already installed?

Thanks in advance

13 Feb
1 month ago

Gabotronix left a reply on Can't Use My Own Dns On Local Machine

@CRONIX - More info on how to do this? do I need to change anything in my laravel app or only apache?

Gabotronix started a new conversation Can't Use My Own Dns On Local Machine

Hi everybody, I edited my apache's vhosts and hosts file in order to use costadog.dev instead of localhost, problem is I'm getting an error page telling me about how my web is not secure and whatnot, this is the page: https://i.imgur.com/qIb0YEU.png

I also tried making a self signed certificate following this tutorial but I'm getting the same error page: https://shellcreeper.com/how-to-create-valid-ssl-in-localhost-for-xampp/

These are my config files:

<VirtualHost costadog.dev:80>
     DocumentRoot "C:\xampp\htdocs\Costadog7\public"
     ServerName costadog.dev
 </VirtualHost>
 <VirtualHost costadog.dev:443>
     DocumentRoot "C:\xampp\htdocs\Costadog7\public"
     ServerName costadog.dev
     SSLEngine on
     SSLCertificateFile "certs/costadog.dev/server.crt"
     SSLCertificateKeyFile "certs/costadog.dev/server.key"
 </VirtualHost>
127.0.0.1   costadog.dev

Gabotronix started a new conversation Can't Login On PhpMyAdmin

Hi everybody, after creating a new user and removing others I can't login into phpMyAdmin! I tried deleting my browser cookies and cache but it's not working.

I'm getting the following error screen:

Fatal error: Uncaught Error: Call to a member function exists() on null in C:\xampp\phpMyAdmin\libraries\classes\DatabaseInterface.php:1544 Stack trace: #0 C:\xampp\phpMyAdmin\libraries\classes\DatabaseInterface.php(2477): PhpMyAdmin\DatabaseInterface->postConnectControl() #1 C:\xampp\phpMyAdmin\libraries\common.inc.php(358): PhpMyAdmin\DatabaseInterface->connect(257) #2 C:\xampp\phpMyAdmin\index.php(26): require_once('C:\xampp\phpMyA...') #3 {main} thrown in C:\xampp\phpMyAdmin\libraries\classes\DatabaseInterface.php on line 1544

Any idea how I can fix this? I guess I could uninstall XAMP and install again but that's kind of a bummer...

11 Feb
1 month ago

Gabotronix left a reply on Vue: Issue Applying Css When Scrolled To Bottom Of Page

@CRONIX - Yes, it does! But no change of color

Gabotronix started a new conversation Vue: Issue Applying Css When Scrolled To Bottom Of Page

Hi everybody, I created a fixed position button, when I scroll to the bottom of the page I want to apply a css style to the button, I'm suing a computed property so it's reactive but the style is not applying, this is because the computed property is not updating and is always false, why is this?

Here is my component:

<template>
<div :class="{ at_bottom : isAtBottom }" class="LAYOUTbutton1_maincontainer" @click="scrollToY()"></div>
</template>
<!--SCRIPTS-->
<script>
export default{
name: 'LAYOUTbutton1',

computed: {
    isAtBottom: function() { 
        return this.atBottom;
    }
},


data() {
    return {
        atBottom: false,
    }
},


mounted () {
    console.log(this.$options.name+' component successfully mounted');

    window.onscroll = function() {
        if ((window.innerHeight + Math.ceil(window.pageYOffset)) >= document.body.offsetHeight) {
            alert('at bottom');
            this.atBottom = true;
        }
        else{
            this.atBottom = false;   
        }
    };
},


methods:{

    scrollToY: function(){
        if(this.atBottom){
            window.scrollTo(0,document.body.scrollHeight);    
        }
        window.scrollTo(0,0);
    }
}


}
</script>
<!--STYLES-->
<style scoped>
.at_bottom{background-color:green !important;}
.LAYOUTbutton1_maincontainer{width:60px; height:60px; background-color:red; position:fixed; right:25px; bottom:25px;}
</style>


Gabotronix left a reply on Showing Custom Error Page

I edited the OP

Gabotronix started a new conversation Showing Custom Error Page

Hi everybody, I have a noob question, I want to use a custom error page (like 404 or 500 errors) when an exception is catched, so that if something goes wrong I can render something like: return view (errors.error , compact( 'status_code' )). I guess the place to do this would be the Exceptions Handler class in laravel.

Mine looks like this:

<?php
namespace App\Exceptions;


use Exception;
use Stripe\Error\Card;
use Stripe\Error\ApiConnection;
use Stripe\Error\InvalidRequest;
use Stripe\Error\Authentication;
use Stripe\Error\RateLimit;
use Stripe\Error\Base;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;


class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        if ($exception instanceof ApiConnection) {
            return response()->json([
                'message' => 'ApiConnection exception, Network communication with Stripe failed.',
            ]);
        }
    
        if ($exception instanceof InvalidRequest) {
            return response()->json([
                'message' => 'InvalidRequest exception, Invalid parameters were supplied to Stripe API.'
            ]);
        }

        if ($exception instanceof Authentication ) {
            return response()->json([
                'message' => 'Api exception, Authentication with Stripe API failed.',
            ]);
        }

        if ($exception instanceof Card) {
            return response()->json([
                'message' => 'Card exception, the card was declined.',
            ]);
        }

        if ($exception instanceof RateLimit) {
            return response()->json([
                'message' => 'RateLimit exception, Too many requests made to the API too quickly',
            ]);
        }

        if ($exception instanceof Base) {
            return response()->json([
                'message' => 'Base exception, one of our programmers need some coffee.',
            ]);
        }

        return parent::render($request, $exception);
    }
}

10 Feb
1 month ago

Gabotronix started a new conversation Returning False And A Value From Function?

Hi everybody, I'm making a shopping cart functionality, I have a function Ifor checking if the items in the cart have enough stock left (comparing cart items quantity and product stock left).

With this function I would do something like:

$hasStock = $this->hasEnoughStockLeftToBuy( $cartItems ) ;

if($hasStock){
    //charge customer and empty cart
}

I would also like this function to return the id of the cart item that checks negative(not enough stock left) but I don't know how to do this, I can only think of returning true or false, how can I say: this item has no stock left, also return the id of said item.

This is what I have so far:

public function hasEnoughStockLeftToBuy($cartItems){
        foreach($cartItems as $item){
            $quantity = $item->quantity;
            $discount = Discount::getBySlug($cart->slug);
            $stockLeft = $discount->stock_left;
            if($quantity < $stockLeft){
                return false;
                //any way to return false along with item id?
            }
        }
        return true;
    }

This might be a noob question but any advice or suggestions is greatly appreciated!

Gabotronix started a new conversation Stripe: Can't Attach Card Holder Name To Stripe Card Source

Hi everybody, I'm trying to attach the name of the cardholder to a newly created source with stripe's elements.js.

However when I submit my form I get the following error:

Received unknown parameter: name

I attach an object with that info in the createSource function, like this:

$('#payment-form').submit(function(e) {
        console.log('submitted');
        e.preventDefault();

        stripe.createSource(cardNumberElement, { name: self.cardHolder }).then(function(result) {
            if (result.error) {
                self.cardErrors = result.error.message;
            } 
            else {
                stripeSourceHandler(result.source);
            }
        });
    });

Is there any other way to store cardholder name into sources?

09 Feb
1 month ago

Gabotronix started a new conversation Stripe: Not Getting Cards Back After Creating Customer

Hi everybody, I'm testing Stripe PHP integration for my web app, I have finally succesfully created a customer and a source (using test card data from stripe's web). Wht I do is collect info with stripe elements, then I do an axios call with card generated source, in my laravel backend I create a new customer and attach created source to customer, then I retrieve the customer sources BUT I'm getting a empty array, no sources are retrieved from my newly created customer...

Here is my controller method (I create customer here and attach source at same time, as seen in the dcs):

public function createSourceAndCustomer(Request $request){

        $user = Auth::user();
        
        if(!$user){
            return response()->json([
                'message' => 'Error, user not found.',
            ], 500);
        }

        $customer = Customer::create([
            "source" => $request->input('source.id'),
        ]);

        $user->stripeId = $customer->id;
        $user->save();

        $customerSources = Customer::retrieve( $user['stripeId'] )->sources->all(array("object" => "card"));

        return response()->json([
            'message' => 'Success, Customer created and source retrieved.',
            'customer' => $user,
            'customerSources' => $customerSources,
            'checkoutStatus' => 2
        ], 200);
   
    }

This is my JSON response, notice empty data array where my card should be. https://i.imgur.com/WyFc8tX.jpg

This is my vue component where I have my elements.js and stripe.js integration:

<template>
<div class="STRIPEform51_maincontainer">
    <layout-title-4 :number="2" :text="'Datos de pago'"></layout-title-4>
    <div class="STRIPEform51_column_container">
        <form id="payment-form" class="STRIPEform51_form_maincontainer" method="POST" action="/stripe/create-source-and-customer">
            <div class="STRIPEform51_form_header_container">
                <span class="STRIPEform51_form_header_label_medium">Nombre del titular</span>
                <span class="STRIPEform51_form_header_label_medium">Número de tarjeta</span>
                <span class="STRIPEform51_form_header_label_small">Caduca</span>
                <span class="STRIPEform51_form_header_label_small">CVC</span>
            </div>
            <div class="STRIPEform51_form_inputs_container">
                <input class="STRIPEform51_form_inputs_input_medium" type="text" v-model="cardHolder">
                <div class="STRIPEform51_form_inputs_input_medium" id="card-number-element"></div>
                <div class="STRIPEform51_form_inputs_input_small" id="card-expiry-element"></div>
                <div class="STRIPEform51_form_inputs_input_small" id="card-cvc-element"></div>
            </div>
            <div class="STRIPEform51_form_buttons_container">
                <div class="STRIPEform51_form_buttons_errors_container">
                    <i class="STRIPEform51_form_buttons_errors_icon fas fa-times" v-show="error"></i>
                    <span class="STRIPEform51_form_buttons_errors_text" v-show="error">{{ error }}</span>
                </div>
                <button class="STRIPEform51_form_buttons_button_container" type="button">
                    <span class="STRIPEform51_form_buttons_button_text"> Añadir tarjeta</span>
                </button>
            </div>
        </form>
    </div>
    <div class="STRIPEform51_column_container">
        <layout-title-4 :number="3" :text="'Confirmar pedido'"></layout-title-4>
        <div class="discount_buy_container">
            <div class="discount_buy_price_container">
                <span class="discount_buy_price_label">Precio total:</span>
                <span class="discount_buy_price_value">{{ cartTotalPrice }}€</span>
            </div>
            <button class="discount_buy_price_button" @click="charge( cartItems )">Finaizar compra</button>
        </div>
        <div class="discount_notice_maincontainer">
            <div class="discount_notice_message_container">
                <div class="discount_notice_message_icon_container">
                    <i class="discount_notice_message_icon fa fa-lock"></i>
                    <span class="discount_notice_message_icon_text">Compra segura</span>
                </div>
                <a class="discount_notice_message_text" href="">(saber mas...)</a>
            </div>
        </div>
    </div>
</div>
</template>
<!--SCRIPTS-->
<script>
import { stripePK } from '../../config/stripe.js';
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
name: 'STRIPEform51',


computed:{
    ...mapState('Stripe', ['customer', 'customerSources', 'loadingStatus', 'errors']),
    ...mapGetters('Cart', ['cartTotalPrice']),
},


data: function () {
    return {
       showPaymentForm: false, 
       stripePK: stripePK,
       cardHolder: '',
       error:'',
    }
},


mounted() {
    console.log(this.$options.name + ' component succesfully mounted');
    this.getCustomerSources();
    var self = this;

    let stripe = Stripe(this.stripePK);
    let elements = stripe.elements();

    let style = {
        base: {
            color: 'rgba(0,0,0,0.7)',
            fontSmoothing: 'antialiased',
            fontSize: '16px',

            '::placeholder': {
                color: 'rgba(0,0,0,0.7)'
            }
        },
        
        invalid: {
            color: '#fa755a',
            iconColor: '#fa755a'
        }
    };

    let cardNumberElement = elements.create('cardNumber', {style: style});
    cardNumberElement.mount('#card-number-element');

    let cardExpiryElement = elements.create('cardExpiry', {style: style});
    cardExpiryElement.mount('#card-expiry-element');

    let cardCvcElement = elements.create('cardCvc', {style: style});
    cardCvcElement.mount('#card-cvc-element');

    cardNumberElement.addEventListener('change', function(event) {
        if (event.error) {
            self.error = event.error.message
        } 
        else {
            self.error = '';
        }
    });

    cardExpiryElement.addEventListener('change', function(event) {
        if (event.error) {
            self.error = event.error.message
        } 
        else {
            self.error = '';
        }
    });

    cardCvcElement.addEventListener('change', function(event) {
        if (event.error) {
            self.error = event.error.message
        } 
        else {
            self.error = '';
        }
    });

    $('#payment-form').submit(function(e) {
        console.log('submitted');
        e.preventDefault();

        stripe.createSource(cardNumberElement).then(function(result) {
            if (result.error) {
                self.error = result.error.message;
            } 
            else {
                stripeSourceHandler(result.source);
            }
        });
    });

    function stripeSourceHandler(source) {
        
        let cardInfo = {
            source: source,
            name: self.cardHolder,
        }

        console.log(cardInfo);
        self.createSourceAndCustomer(cardInfo);
    }
},


methods: {
    ...mapActions('Stripe', ['getCustomerSources', 'addSource', 'charge', 'createSourceAndCustomer']),

    togglePaymentForm: function(){
        this.showPaymentForm = !this.showPaymentForm;
    },
}


};
</script>

When I create source from elements I get a source id console logged so afaik the card is indeed generated, you can see it here: https://i.imgur.com/4ty37N9.jpg

07 Feb
1 month ago

Gabotronix started a new conversation Question About Web Deployment In Ubuntu/Windows

Hi everybody, when I'm learning and tinckering with web development I work on windows 10 but I have heard good things about ubuntu, the thing is I want to deploy my first test web apps using Digital Ocean which apparently is pretty ggod, DO vps use ubuntu and most of the tutorials I have seen on web deployment use Ubuntu for this.

I's like to be able to use windows for watching netflix and ubuntu for web development, what would be the best way to do this?

should I create a virtual machine with ubuntu in my laptop? will this make my laptop run slower? sorry for the noob question but I'd love to hear some suggestions.

Gabotronix started a new conversation Stripe: Multiple Elements Payment Forms Possible?

Hi everybody, I'm trying to have two payment forms in a single component, problem is I'm getting the following error:

Can only create one Element of type cardNumber

At first one of the forms will be hidden but the user can choose to make the other appear clicking a button to add a new source.

Is it possible to have more than one payment form in the same page?

This is my full component:

<template>
<div class="STRIPEform21_maincontainer">
    <layout-title-4 :number="2" :text="'Elije tu forma de pago.'"></layout-title-4>
    <form v-show="!showPaymentForm" id="payment-form" method="POST" class="STRIPEform21_form_maincontainer">
            <div class="STRIPEform21_form_row_container">
                <span class="STRIPEform21_form_row_label">Nombre del titular</span>
                <input class="STRIPEform21_form_row_input" type="text">
            </div>
            <div class="STRIPEform21_form_row_container">
                <span class="STRIPEform21_form_row_label">Número de tarjeta</span>
                <div id="card-number-element" class="STRIPEform21_form_row_input"></div>
            </div>
            <div class="STRIPEform21_form_row_container">
                <span class="STRIPEform21_form_row_label">Fecha de caducidad</span>
                <div id="card-expiry-element" class="STRIPEform21_form_row_input"></div>
            </div>
            <div class="STRIPEform21_form_row_container">
                <span class="STRIPEform21_form_row_label">CVC</span>
                <div id="card-cvc-element" class="STRIPEform21_form_row_input"></div>
            </div>
            <button class="STRIPEform21_form_button_container" type="submit" @click="addSource();">
                <span class="STRIPEform21_form_button_text">Añadir</span>
            </button>
        </form>
    <div class="STRIPEform21_column_container">
        <div class="STRIPEform21_select_row_container">
            <span class="STRIPEform21_select_row_label">Elije tu forma de pago:</span>
            <select class="STRIPEform21_select_row_input">
                <option class="STRIPEform21_select_row_option" >✱✱✱✱ ✱✱✱✱ ✱✱✱✱ 4242 - 05/22</option>
            </select>
        </div>
        <div class="STRIPEform21_column_center_container">
            <span class="STRIPEform21_column_text">O elije otra opción:</span>
            <button class="STRIPEform21_column_button_container" @click="showPaymentForm = true">
                <i class="STRIPEform21_column_button_icon fa fa-plus"></i>
                <img class="STRIPEform21_column_button_image" src="/img/misc/credit-cards/rectangle-generic.svg">
                <span class="STRIPEform21_column_button_text">Añadir otra tarjeta de credito</span>
            </button>
        </div>
    </div>
    <div v-show="showPaymentForm" class="STRIPEform21_tab_container">
        <i class="STRIPEform21_close fa fa-times" @click="showPaymentForm = false;"></i>
        <form id="payment-form" method="POST" class="STRIPEform21_form_maincontainer">
            <div class="STRIPEform21_form_row_container">
                <span class="STRIPEform21_form_row_label">Nombre del titular</span>
                <input class="STRIPEform21_form_row_input" type="text">
            </div>
            <div class="STRIPEform21_form_row_container">
                <span class="STRIPEform21_form_row_label">Número de tarjeta</span>
                <div id="card-number-element-2" class="STRIPEform21_form_row_input"></div>
            </div>
            <div class="STRIPEform21_form_row_container">
                <span class="STRIPEform21_form_row_label">Fecha de caducidad</span>
                <div id="card-expiry-element-2" class="STRIPEform21_form_row_input"></div>
            </div>
            <div class="STRIPEform21_form_row_container">
                <span class="STRIPEform21_form_row_label">CVC</span>
                <div id="card-cvc-element-2" class="STRIPEform21_form_row_input"></div>
            </div>
            <button class="STRIPEform21_form_button_container" type="submit" @click="addSource();">
                <span class="STRIPEform21_form_button_text">Añadir</span>
            </button>
        </form>
    </div>
</div>
</template>
<!--SCRIPTS-->
<script>
import { stripePK } from '../../config/stripe.js';
import { mapState, mapActions } from 'vuex';
export default {
name: 'STRIPEform31',


computed:{
    ...mapState('Stripe', ['customer', 'customerSources', 'loadingStatus', 'errors']),
},


data: function () {
    return {
       showPaymentForm: false, 
       stripePK: stripePK,
    }
},


props: {
    globals: {required:true}
},


mounted() {
    console.log(this.$options.name + ' component succesfully mounted');
    this.getCustomerSources();

    let stripe = Stripe(this.stripePK);
    let elements = stripe.elements();

    // Custom styling can be passed to options when creating an Element.
    let style = {
        base: {
            color: 'rgba(0,0,0,0.7)',
            fontSmoothing: 'antialiased',
            fontSize: '16px',

            '::placeholder': {
                color: 'rgba(0,0,0,0.7)'
            }
        },
        
        invalid: {
            color: '#fa755a',
            iconColor: '#fa755a'
        }
    };

    // Create an instance of the card Element.
    //let card = elements.create('card', {style: style});
    //card.mount('#card-element');

    let cardNumberElement = elements.create('cardNumber', {style: style});
    cardNumberElement.mount('#card-number-element');

    let cardExpiryElement = elements.create('cardExpiry', {style: style});
    cardExpiryElement.mount('#card-expiry-element');

    let cardCvcElement = elements.create('cardCvc', {style: style});
    cardCvcElement.mount('#card-cvc-element');

    let cardNumberElement2 = elements.create('cardNumber', {style: style});
    cardNumberElement2.mount('#card-number-element2');

    let cardExpiryElement2 = elements.create('cardExpiry', {style: style});
    cardExpiryElement2.mount('#card-expiry-element-2');

    let cardCvcElement2 = elements.create('cardCvc', {style: style});
    cardCvcElement2.mount('#card-cvc-element-2');

    // Handle real-time validation errors from the card Element.
    cardNumberElement.addEventListener('change', function(event) {
        if (event.error) {
            $('#card-errors').text(event.error.message);
        } 
        else {
            $('#card-errors').text('');
        }
    });

    // Handle form submission.
    $('#stripe_form').submit(function(e) {
        e.preventDefault();

        stripe.createSource(cardNumberElement).then(function(result) {//or card
            if (result.error) {
                // Inform the user if there was an error.
                $('.card-errors').text(result.error.message);
            } 
            else {
                // Send the source to your server.
                stripeSourceHandler(result.source);
            }
        });
    });

    // Submit the form with the source ID.
    function stripeSourceHandler(source) {
        // Insert the source ID into the form so it gets submitted to the server
        let form = $('#stripe_form');

        $('<input>').attr({
            type: 'hidden',
            name: 'stripeSource',
            value: source.id,
        }).appendTo('form');

        // Submit the form
        form.submit();
    }
},


methods: {
    ...mapActions('Stripe', ['addSource', 'getCustomerSources']),

    openPaymentTab: function(){
        this.paymentTab = true;
    },

    closePaymentTab: function(){
        this.paymentTab = true;
    }
}


};
</script>
<!--STYLES-->
<style scoped>
</style>
06 Feb
1 month ago

Gabotronix started a new conversation Vue: Issue With Adding Items To Shopping Cart

Hi everybody, I'm making my own shopping cart for learning js and vue, I'm suing vuex modules for state management and persist data in local storage. Everything works fine but adding X ammount of items acts really irregular(sums doesn't seem right, sometimes it decreases quantity instead of increasing.);

My shopping cart can hold different discounts (products).

One discount object looks like this (Iaravel spits this in JSON from):

"id" => 1
    "slug" => "descuento-muy-wow"
    "url" => "/descuentos/descuento-muy-wow"
    "title" => "Descuento muy wow"
    "body" => "<p>Descripcion del contenido</p>"
    "originalPrice" => "12.99"
    "finalPrice" => "10.99"
    "discountPercent" => 15
    "people" => 1
    "codesToGenerate" => 10
    "image" => "/uploads/file-06-02-2019-01-17-VFL-247.jpeg"
    "isVisible" => 1
    "expireDate" => "2019-02-06 02:17:20"
    "created_at" => "2019-02-06 01:17:14"
    "updated_at" => "2019-02-06 01:17:20"

Method getDiscountData takes a discount as argument, then adds a new quantity property and sends it t the vuex action addProductToCart, then a mutation increments the cart item quantity by by this.quantity.

This is how I add items to cart and increase item quantity, I'm ALMOST POSITIVE that the error is in how I do the sum , in the mutation INCREASE_ITEM_QUANTITY;

const mutations = {

    ADD_PRODUCT_TO_CART(state, product) {
        state.cartItems.push(product);
    },

    INCREASE_ITEM_QUANTITY(state, product) {
        let index = state.cartItems.findIndex(item => item.id == product.id);
        state.cartItems[index].quantity = parseInt(state.cartItems[index].quantity) + parseInt(product.quantity);
    },

This is my component where click event is registered:

<template>
<div class="DISCOUNTcard3_maincontainer">
    <div class="DISCOUNTcard3_image_container">
        <div class="DISCOUNTcard3_image" :style="'background-image:url('+discount.image+');'"></div>
    </div>
    <div class="DISCOUNTcard3_info_container">
        <span class="DISCOUNTcard3_info_title">{{ discount.title }}</span>
        <span class="DISCOUNTcard3_info_price">{{ discount.finalPrice }} €</span>
        <div class="DISCOUNTcard3_info_quantity_container">
            <span class="DISCOUNTcard3_info_quantity_label">Cantidad:</span>
            <div class="DISCOUNTcard3_info_quantity_inputs_container">
                <input class="DISCOUNTcard3_quantity_inputs_input" v-model="quantity" type="number" step="1" min="1" :max="discount.stock_left">
                <button class="DISCOUNTcard3_quantity_inputs_button" type="button" @click="getDiscountData(discount);">
                    <span class="DISCOUNTcard3_quantity_inputs_button_text">AÑADIR A LA CESTA</span>
                </button>
            </div>
        </div>
        <div class="DISCOUNTcard3_info_description" v-html="discount.body"></div>
    </div>
</div>
</template>
<!--SCRIPTS-->
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
name: 'DISCOUNTcard3',


data() {
    return {
        quantity: 1,
    }
},


props: {
    discount: { required:true }
},


mounted() {
    console.log(this.$options.name+' component successfully mounted');
},


methods:{
    ...mapActions('Cart', ['addProductToCart']),

    getDiscountData: function(discount){
        alert('dataquant:'+this.quantity);
        discount.quantity = parseInt(this.quantity);
        alert('quant:'+discount.quantity);
        this.addProductToCart(discount);
        console.log('clicked add to cart...');
    }
}


};
</script>
05 Feb
1 month ago

Gabotronix started a new conversation Vue: Getting Undefined Error

Hi everybody, I'm trying to make a shopping cart unsing vuex module as state management solution, HOWEVER when I loop through the cart items to see if product is already added I get the following error:

TypeError: state.cartItems[i] is undefined

This is my action:

addProductToCart({commit, state}, product) {

        if(product.stock_left){
            for(var i=0; i<=state.cartItems.length; i++){
                if(state.cartItems[i].id == product.id){
                    commit('ADD_PRODUCT_TO_CART', product);   
                }
            }
            commit('INCREASE_ITEM_QUANTITY', product);
        }
        
    },

And my initial state object:

const state = {
    allProducts: [],
    cartItems: [],
    checkoutDetails: {},
    showCartTab: false,
    quantity: 2,
    loadingStatus: 0,
    errors: []
}

Any suggestions or ideas to solve this, do this better?

04 Feb
1 month ago

Gabotronix started a new conversation Vue: Methods Inside Vuex Module

Hi everybody, I'm trying to make a shopping cart functionality using vuex modules for easy state management, inside actions I created two helper functions to check if producht has stock left and if it's already in the cart, HOWEVER when I execute addProductToCart I get the following error in console:

TypeError: this.productHasStockLeft is not a function

This is my vuex cart module actions:

const actions = {


    checkout({ state, commit, dispatch}) {
        commit('SET_LOAD_STATUS', 1);
        axios.post('/cart/checkout', state.cartItems)
        .then((response) => {
            commit('PRINT_CHECKOUT_DETAILS', response.data.checkoutDetails );
            commit( 'SET_LOAD_STATUS', 2);
        }, 
        (error) => {
            dispatch('handleErrors', error);
        })
    },


    addProductToCart({commit}, product) {
    
        if (this.productHasStockLeft(product) && this.productIsInCart(product)) {
            commit('ADD_PRODUCT_TO_CART', product )
        }

        if (this.productHasStockLeft(product) && !this.productIsInCart(product)) {
            commit('INCREMENT_ITEM_QUANTITY', product )
        }
    },


    productIsInCart: function (product){
        return state.cartItems.find(item => item.id === product.id)
    },


    productHasStockLeft: function(product){
        return product.stock_left > 0;
    },

    increaseProductQuantity({state, commit}, product){
        let productToIncrease = _.find(state.allProducts, [ 'id', product.id]);
        if (productToIncrease.quantity > 0){
            commit('INCREASE_PRODUCT_QUANTITY', 1);
        }
    },
}

Any idea or suggestions? Thanks in advance.

Gabotronix started a new conversation Accesor Not Available In JSON Response

Hi everybody, yesterday I discovered accesors thanks to the community:

https://laracasts.com/discuss/channels/general-discussion/attach-property-to-eloquent-model

They appear to be really handy computed properties for my backend models HOWEVER, I just noticed that they are not retained in the response. That is, on my vue components I don't have access to these properties, they aren't just there. This is SUCH a bummer...

So my question is, how can I make the accessors be retained in the JSON response so I can use these in my views!

So I can use discount.stockLeft in my vue components.

My accessor example:

public function getStockLeftAttribute()
    {
        return collect($this->discountcodes)->reject(function ($code) {
            return $code->isBought;
        })->count();
    }