nolros

nolros

Member Since 5 Years Ago

Experience Points 87,870
Experience Level 18

2,130 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 383
Lessons
Completed
Best Reply Awards 29
Best Reply
Awards
  • start-engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-session Created with Sketch.

    School In Session

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

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

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

  • subscriber-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist Created with Sketch.

    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 Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

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

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

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

03 Sep
2 weeks ago

nolros left a reply on DateTime

@rider

There are a lot of ays to get it done, but assume it is in your model as a accessor (example assumes published at date)

    public function getPublishedAtAttribute($value)
    {
        return (new Carbon($value))->setTimezone('America/Denver')->-format(\DateTime::ISO8601);
    }

``

nolros left a reply on Illuminate \ Database \ QueryException (HY000) SQLSTATE[HY000]: General Error: 1364 Field 'p_id' Doesn't Have A Default Value (SQL: Insert Into `prod_cats` (`updated_at`, `created_at`) Values (2019-09-03 05:18:24, 2019-09-03 05:18:24))

@kanchan186

   
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\prod_cat;
use App\product;
use App\category;

class ProdCatController extends ProductController
{
   public function store1(Request $request)
    {

        if ($request->p_id && $request->p_id ) {

        if ($categor = prod_cat::create([
                'p_id'=>$request->p_id,
                'c_id'=>$request->c_id
               ]);) {

            // remove the rest for brevity sake 

            return response('Product category created successfully', 200);

        }

        // or whatever you want to do when it fails
        return response('Failed to find ids', 422);
    }
}


nolros left a reply on Countdown Timer

@matilarab here is a Vue countdown

  1. Load moment.js

  2. create Vue compoenent - countdown.vue


<template>
    <div class="countdown__container">
        <div v-if="finished" v-text="expiredText"></div>

        <div v-else class="countdown__date--container">
            <div class="countdown__item">
                <span class="countdown__heading">Days</span>
                <div class="countdown__date--item">
                    <span>{{ remaining.days }}</span>
                </div>
            </div>

            <div class="countdown__item">
                <span class="countdown__heading">Hours</span>
                <div class="countdown__date--item">
                    <span>{{ remaining.hours }}</span>
                </div>
            </div>
            <div class="countdown__item">
                <span class="countdown__heading">Seconds</span>
                <div class="countdown__date--item">
                    <span>{{ remaining.seconds }}</span>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import moment from 'moment';

    export default {
        props: {
            until: String,
            expiredText: { default: 'Now Expired' }
        },
        data () {
            return { now: new Date() };
        },
        created () {
            this.refreshEverySecond();
        },
        computed: {
            finished () {
                return this.remaining.total <= 0;
            },
            remaining () {

                let remaining = moment.duration(Date.parse(this.until) - this.now);

                if (remaining <= 0) this.$emit('finished');

                return {
                    total: remaining,
                    years: this.pad(remaining.years(),2),
                    months: this.pad(remaining.months(),2),
                    days: this.pad(remaining.days(),2),
                    hours: this.pad(remaining.hours(),2),
                    minutes: this.pad(remaining.minutes(),2),
                    seconds: this.pad(remaining.seconds(),2)
                };
            }
        },
        methods: {

           pad(num, size) {
                var s = "000000000" + num;
                return s.substr(s.length-size);
            },
            refreshEverySecond () {
                let interval = setInterval(() => this.now = new Date(), 1000);
                this.$on('finished', () => clearInterval(interval));
            }
        }
    }
</script>

  1. SCSS - countdown.scss

NOTE: I have not made it responsive. Would need a little work for mobile.


.countdown__shadow {
  &:before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 40px;
    //height: 100%;
    //background: rgb(51,51,51);
    background: linear-gradient(180deg, rgba(51,51,51,0.6) 0%, rgba(255,255,255,0) 100%);
  }
}

.countdown__bg {
  background-color: #f1f1f1;
  box-shadow: inset 10px 0 20px rgba(0, 0, 0, 0.1),
    inset -10px 0 20px rgba(0, 0, 0, 0.1);
  height: auto;
  padding: 0 30px 60px 30px;
}

.countdown__container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  width: 100%;

  //height: 400px;
  & .countdown__date--container {
    display: flex;
    flex-direction: row;
    justify-content: center;
    width: 100%;
    height: 150px;
    & .countdown__item {
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      padding: 5px;
      width: 10%;

      & .countdown__heading {
        width: 100%;
        margin-bottom: 5px;
        text-align: center;
        font: 300 1.6rem Raleway, sans-serif;
        text-transform: uppercase;
        letter-spacing: -0.5px;
        strong {
          font-weight: 400;
          color: #ea4c4c;
        }
      }

      & .countdown__date--item {
        position: relative;
        float: left;
        height: 110px;
        width: 100px;
        background-color: #fff;
        border-radius: 8px;
        box-shadow:0 3px 4px 0 rgba(0, 0, 0, .2),inset 2px 4px 0 0 rgba(255, 255, 255, .08);

        left: 0;
        right: 0;
        margin: auto;
        font: normal 5.94em/107px Oswald;
        font-weight: 700;
        color: #de4848;
        color: $color-orange-burnt;

        text-align: center;
      }
    }
  }
}

.countdown__heading-date {
  position: relative;
  display: block;
  width: 100%;
  margin: 0;
  line-height: 1rem;
  text-align: center;
  color: #555555;
  font: 100 2rem Oswald, sans-serif;
  text-transform: uppercase;
}

  1. in your HTML / Blade - set your date
                <countdown until="Dec 1, 2019"></countdown>

nolros left a reply on CSS For Backend Devs: Episode 7: Can't Get Tailwind Hooked Up

@oscarmoore normally that happens if you are runnng

Composer.json

{
    "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": {
        "axios": "^0.19",
        "browser-sync": "^2.26.7",
        "browser-sync-webpack-plugin": "2.2.2",
        "cross-env": "^5.2",
        "laravel-mix": "^4.1.2",
        "laravel-mix-purgecss": "^4.1.0",
        "laravel-mix-tailwind": "^0.1.0",
        "lodash": "^4.17.15",
        "popper.js": "^1.15",
        "resolve-url-loader": "^3.1.0",
        "sass": "^1.22.10",
        "sass-loader": "^8.0.0",
        "tailwindcss": "^1.1.2",
        "vue": "^2.6.10",
        "vue-template-compiler": "^2.6.10",
        "clean-webpack-plugin": "^3.0.0",
        "purgecss-webpack-plugin": "^1.5.0",
        "purify-css": "^1.2.5",
        "purifycss-webpack": "^0.7.0",
        "webpack-bundle-analyzer": "^3.4.1",
        "webfontloader": "^1.6.28",
        "vue-loader": "^15.7.1"
    },
    "dependencies": {
        "moment": "^2.24.0",
    }
}

webpack.mix.js

NOTE: 1 ensure you have installed laravel-mix-tailwind i.e. npm install laravel-mix-tailwind --dev

  1. I dont use the sass loader / compiler but if you do then that would be in mix file
const mix = require('laravel-mix');

  require('laravel-mix-tailwind');
  require('laravel-mix-purgecss');

  /*
   |--------------------------------------------------------------------------
   | 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.
   |
   */


  mix.js('resources/js/app.js', 'public/js')
      .postCss('resources/css/app.css', 'public/css')
      .tailwind()
      .options({
          processCssUrls: false,
      })
      .purgeCss();

That you tailwind.js is in your root directory

module.exports = {
  theme: {
    extend: {}
  },
  variants: {},
  plugins: []
}

app.scss


@tailwind base;

@tailwind components;

@tailwind utilities;

02 Sep
2 weeks ago

nolros left a reply on Post Comment Form With Ajax

You are submitting the form using PHP versus AJAX / JQ ... so do something like this ...

FORM BLADE

  {!! Form::open(array('id'=>'myform')) !!}
    <div class="form-group" >
      {!! Form::label('comment',' ')  !!}
      {!! Form::textarea('comment',null,['placeholder'=>'Add a comment...','class' => 'form-control showbutton', 'rows'=>'1']) !!}    
    </div>
    {!! Form::hidden('id', $images->id) !!}
    <div class="form-group buttoncomment">
            <button class="send btn btn-danger" id="ajaxSubmit">Submit</button>
    </div>
  {!! Form::close() !!}


<script>
     $(document).ready(function(){
      $('#ajaxSubmit').click(function(e){
         e.preventDefault();
         $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
            }
        });
         $.ajax({
            url: "{{ url('/home/comment') }}",
            method: 'post',
            data: {
               name: $('#name').val(),
               type: $('#type').val(),
               price: $('#price').val()
            },
            success: function(result){
               console.log(result);
            }});
         });
      });
</script>

CONTROLLER

       public function store(Request $request)
       {
        if(Request::ajax()){
              $comment = new Comment();
              $comment->name = $request->name;
              $comment->type = $request->type;
              $comment->price = $request->price;

              $comment->save();
              return response()->json(['success'=>'Data is successfully added']);
        
    endif
       }

nolros left a reply on Jigsaw / Mix / Fontawesome

Fonts and webpack is a pain, but for SEO almost a must.

package.json

Install fortawesome, webfontloader and vue-fontawesome (Vue fontawesome component)


    {
      // <omitted for brevity sake>

      "devDependencies": {
       // <removed for brevity sake>

        "@fortawesome/fontawesome-free": "^5.8.1",
        "@fortawesome/fontawesome-svg-core": "^1.2.17",
        "@fortawesome/vue-fontawesome": "^0.1.6",
        "@fortawesome/free-brands-svg-icons": "^5.8.1",
        "@fortawesome/free-solid-svg-icons": "^5.8.1",
        "webfontloader": "^1.6.28"
      },
      "dependencies": {
      // <omitted for brevity sake>
      }
    }

wepack.mix.js

Install web font loader and require it in webpack.mix.js. I use google fonts example, but you can use any font. That said, I have not tested fontawesome.

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

    require('laravel-mix-tailwind');
    require('laravel-mix-purgecss');

    if (typeof window !== 'undefined') {
        var WebFont = require('webfontloader');

        WebFont.load({
            google: {
                families: [
                    'Lato:300,500',
                    'Roboto:300,500',
                    'Open+Sans:300,400,600,700',
                    'Montserrat:300,400,500'
                ],
            },
        });
    }


    mix.webpackConfig({
        module: {
            rules: [{
                test: /\.tsx?$/,
                loader: 'ts-loader',
                options: {
                    appendTsSuffixTo: [/\.vue$/],
                },
                exclude: /node_modules/,
            }],
        },
        entry: {
            vendor: [
                "webfontloader"
            ]
        },
        resolve: {
            extensions: ['*', '.js', '.jsx', '.vue', '.ts', '.tsx'],
            alias: {
                styles: path.resolve(__dirname, 'resources/assets/sass'),
                '@': path.resolve(__dirname, 'resources/assets/js'),
                webfontloader: path.resolve(__dirname, "./node_modules/webfontloader/webfontloader.js")
            },
        },
    })

app.js

I have been verbose to help illustrate the different loads from the multiple font-awesome packs, but you can load all and I believe use wildcards. Frankly, Im not a fan of the fontwesome approach and it is a pain in blade.

      … <removed for brevity sake>


    import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
    import { library } from '@fortawesome/fontawesome-svg-core'
    import { faCoffee,faSearch,faMinus,faTimes,faEllipsisV,faPhone,faEnvelope,faMapMarker,faEye,
        faFont,faAddressBook,faAddressCard,faHeart,faFilter,faWindowClose,faCheck,faChevronDown, faChevronRight,faChevronLeft,faTh,faList,faArrowAltCircleRight} from '@fortawesome/free-solid-svg-icons'
    import { faFacebook,faLinkedin,faInstagram,faTwitter,faYoutube,faGithub,faPinterest,faGoogle,faGooglePlus} from '@fortawesome/free-brands-svg-icons'
    library.add(faCoffee,faSearch,faMinus,faTimes,faEllipsisV,faPhone,faEnvelope,faMapMarker,faEye,faFont, faTh,faList,faAddressBook,
        faAddressCard,faHeart,faFilter,faWindowClose,faCheck,faChevronDown,faChevronRight,faChevronLeft,faArrowAltCircleRight);
    library.add(faFacebook,faLinkedin,faInstagram,faTwitter,faYoutube,faGithub,faPinterest,faGoogle,faGooglePlus);
    Vue.component('font-awesome-icon', FontAwesomeIcon);


      … <removed for brevity sake>

example.blade.php

an example element. I ran into problems where I had to be explicit and load the attribute as an array.

    <a itemprop="sameAs"
       title="CMO Solution Twitter"
       target="_blank"
       rel="nofollow"
       href="https://twitter.com/cmo_digital"
       class="linkable">
        <font-awesome-icon class="fab" :icon="['fab', 'twitter']"></font-awesome-icon>
    </a>


Hope that helps. It is a pain. Let me know if you have questions.

18 Mar
6 months ago

nolros started a new conversation Webpack.mix First Render (Critical Rendering Path) Config

Anyone have a best practice or ideally an example for compiling for first paint (Critical Rendering Path) i.e. I would like to compile the core JS and Sass. So that I can minimize initial JS and CSS file size and load. Then defer / async block load the majority of JavaScript and CSS. The purpose is obviously for PageSpeed.

I could just use Webpack vanilla, but wondering if there is a Laravel best practice example.

As a plus if anyone has examples of defer loading third-party scripts like Google Analytics, Facebook API, Twitter, etc. I could write a wrapper, but that almost always goes sideways when an update occurs.

19 Feb
7 months ago

nolros started a new conversation VueJS Render Static HTML

This seems like an obvious or simple ANSWER, but I cannot seem to find an answer. How do I dynamically import a HTML FILE into a Vue component? NOT a template, but lets say I have an article-.html file that I want to pull in dynamically e.g. on click of post abstract show the above mentioned html file. In Laravel it would @include(‘path’) or AngularJS it would be ng-include(‘path)

05 Jan
8 months ago

nolros left a reply on How To Submit A Vue Component In Laravel Blade?

Code would look like below:

btw - you dont need to do this

this.content = this.editcontent; as it redundant

the content can be accessed via this.editconten off props.

BLADE

        <section>

                <editor-by-vue
            :id="{!! $question->id !!}"
                        :editcontent="{!! $question->body !!}">
                </editor-by-vue>

            </section>

VUE

<template>
    <form action="/question/{{ $question->id }}" 
            name="editor"
              @submit.prevent="onSubmit"
              method="post">
        <label for="title">Description</label>
        <vue-editor
                v-model="content"
                :editorToolbar="customToolbar">
        </vue-editor>
        <button  type="submit">Publish</button>
    </form>
</template>


<script>
    import { VueEditor } from 'vue2-editor';

    export default {
        props: [
        'editcontent',
        'id'
    ],
        components: {
            VueEditor
        },
        mounted() {
            this.content = this.editcontent;
        },
        data() {
            return {
                content: '',
                customToolbar: [
                    ['bold', 'italic', 'underline'],
                    [{ 'list': 'ordered'}, { 'list': 'bullet' }],
                    ['image', 'code-block']
                ]
            }
        }

        methods: {

            onSubmit: function () {
                var url = '/question/' + this.id;

                axios.post(url, this.content)
                    .then(response => {

                    })
                    .catch(error => {
                    });

            },
        },
    }
</script>


nolros left a reply on How To Determine If Multiple Records' Are More Than A Value Then Count?

@patricksj assuming they are all in the results table you could do this

     $paperIds = [1,2,3];
        $min = 50;
        $max = 95;
        

    // $count will give you count & $results will be the collection 

        $count = count($results = DB::table('results')
            ->whereIn('paper_id', $paperIds)
            ->whereBetween('mark', [$min, $max])
            ->get());

nolros left a reply on Dynamically Import And Render HTML Documents

@JLRDW - @jlrdw yes I can do it via php but I was looking for an elegant Vue solution. I think the right answer is Vue Directive combined with Vue async https://vuejs.org/v2/guide/components-dynamic-async.html. The issue with php and Vue is that Vue like most JS libraries doesn't work well with dynamic DOM manipulation so you need to compile / render and everything should be promise based to give Vue time to sync the changes. AngularJS solved this with directives and even then it was cycle intensive $digest() $apply(),, $watch()

Vue doesn't seem to have a clean solution. I'm noticing that Vue struggles with some of the earlier DOM issues that AngularJS struggled with. It has issues SEO, dynamic DOM compile / render, etc. However in the absence of AngularJS Vue is the next best solution because ANgular and Laravel is an overkill and frankly not a good fit.

nolros left a reply on How To Change Values Of A Prop If Components Are Produced Via Blade For Loop?

@ANDREASB - Here is the working code

Blade

         <section>

                <followable-icon 
                        title="title: Remove from list"
                        icon="icon:minus-circle; ratio: 0.8"
                        :question-id="{!! $question->id !!}"
                        followable="bookmark"
                        :is-followable=true>
                ></followable-icon >
      

            </section>

Vue

<template>
    <div style="width: 100px; height: 100px; background: red;">
        <a href="#"
           :data-uk-tooltip="title"
           class="uk-icon-link"
           :data-uk-icon="icon"
           @click="toogleFollowable()">Click
        </a>
    </div>
</template>


<script>
    export default {

        props: {
            title: {
                type: String,
                required: true
            },
            icon: {
                type: String,
                required: true
            },
            questionId: {
                type: Number,
                required: true
            },
            followable: {
                type: String,
                required: true
            },
            isFollowable: {
                type: Boolean,
                required: true
            },
        },
        data: function () {
            return {

            }
        },
        methods: {

            toogleFollowable: function (event) {
                var url = '/question/toogleFollowable/' + this.followable+ '/' + this.questionId;

                axios.post(url)
                    .then(response => {
                        this.toogleFollowableUIChanges(event)
                    })
                    .catch(error => {
                        this.error = error;
                    });

            },

            toogleFollowableUIChanges: function (event) {
                switch(this.isFollowable ){
                    case "true":
                        this.icon = "icon:plus-circle; ratio: 0.8";
                        this.isFollowable = "false";
                        break;
                    case "false":
                        this.icon = "icon:minus-circle; ratio: 0.8";
                        this.isFollowable = "true";
                        break;
                }
            },
        },

    }
</script>


03 Jan
8 months ago

nolros left a reply on How To Change Values Of A Prop If Components Are Produced Via Blade For Loop?

example to help you

<!--BLADE FOREACH-->
<ul id="product__card"
    class="product__cards--container list-reset">
    @if(count($category->products))

        @foreach($category->products as $product)
        <product-card
                id="{!! $product->id!!}"
                name="{!! $product->name!!}"
                image-url="{!! $product->image_url!!}"
                dimensions="{!! $product->dimensions!!}"
                projects="{!! $product->projects!!}">
        </product-card>

        @endforeach
    @endif
</ul>



<!--VUE COMP e.g. ProductCard-->
<template>
    <div class="product__card--item">
            <div class="product__card-image--container">
                <img class="product__card-image"
                     itemprop="url"
                     :src="imageUrl"
                     alt="">
            </div>
            <p class="product__card-title">{{name}}</p>
        <div id="product__card-info">
            <ul>
                <li class="product__card-info">
                    <h3 class="text-center">{{dimensions}}</h3>
                    <p class="text-center">dimensions</p>
                </li>
            </ul>
        </div>
    </div>
</template>


<script>
    export default {
        name: 'ProductCard',
        props: {
            id: {
                type: String,
                required: true
            },
            name: {
                type: String,
                required: true
            },
            imageUrl: {
                type: String,
                required: true
            },
            dimensions: {
                type: String,
                required: true
            },
            projects: {
                type: String,
                required: true
            },
        },
        data: function () {
            return {
                active:{}
            }
        },
        methods: {

            tester: function () {
                console.error("click tester");

            }
        }
    }
</script>

nolros left a reply on How To Change Values Of A Prop If Components Are Produced Via Blade For Loop?

You declaring props, but not binding them with :

  1. try this
           <followable-icon 
                        :title="'title: Remove from list" 
                        :icon="icon:minus-circle; ratio: 0.8"
                        :question-id="{!! $question->id!!}" 
                        :followable="bookmark"
                        :is-followable=true>
                    
                </followable-icon>
  1. remove this you've already have them set in props - vue will complain i.e. this.icon will work fine
    data: function () {
      return {
        icon: this.icon,
        questionId: this.questionId,
        followable: this.followable,
        isFollowable: this.isFollowable,
        
      }
    },

nolros left a reply on Return Items Separated Out By Date

You could try something like this, but unsure if you are saving anything.

        $latest = Site::query()
            ->with('upvotes')
            ->where([
                ['is_approved', '=', 2],
                ['is_featured', '=', 1],
            ])->orderBy('created_at', 'DESC')
            ->get()
            ->map(function ($sites) {
                $sites->groupBy(function ($s, $k) {
                    return $s->created_at->toDateString();
                });
                return $sites;
            });

nolros left a reply on How To Update Multiple Forms

I wouldn't recommend this approach, but as long as the forms are contained in a single scope they will all use a single model. You will handle the post outside of the forms with a generic post

please note I have not tested any of this i.e. just conceptual

<template>
    <div> // NOTE: this is in one scope
        <form v-for="(form,index) in forms">
            <input :v-model="model[form.input]"
                   type="{{form.input}}" 
                   id="{{form.input}}">
        </form>
        <button @click="submitForms"></button>
    </div>
</template>

<script>
    export default {
        name: "Example",
        data: function () {
            return {
                htmlDocuments: [
                    {
                        id:1,
                        form: "form-one",
                        input: text
                    },
                    {
                        id:2,
                        form: "form-two",
                        input: email
                    },
                    {
                        id:3,
                        form: "form-three",
                        input: password

                    },
                ],
                model: {
                    email:"",
                    name: "",
                    url: ""
                },
                active:{}

            }
        },
        methods: {
            submitForms: function () {
                const url = '/api/post';

                return new Promise((resolve, reject) => {
                    axios[.post(url, this.model)
                        .then(response => {
                            resolve(response.data);
                        })
                        .catch(error => {
                            reject(error.response.data);
                        });
                });
                
            },
        }

    }
</script>

nolros started a new conversation Dynamically Import And Render HTML Documents

What is the best option to import and render a list html documents / templates that are NOT Vue components

Options:

  1. 'import htmlFile from htmlFile.html' ... the problem is this doesn't work with dynamic list of files i.e. n number of html files
  2. Vue render() function
  3. vue-router but that really works for nav / tabs, etc but in the face of lets say blog posts where all I'm looking do is import and render html then it is not idea

Example in AngularJS the ng-include

<li ng-repeat="item in list">
    <div ng-include="item.source_url'"></div>
</li>

Example HTML Documents

<!--/templates/example-1.html-->
<div>
    <p>Nothing special</p>
</div>

<!--/templates/example-2.html-->
<div>
    @include("php-file-example")
    <p>Php and HTML</p>

</div>

<!--/templates/example-3.html-->
<div>
    <p :text="somevar"></p>
</div>
<!--ExampleComponent-->
<template>
    <ul>
        <li v-for="(document,index) in htmlDocuments">
            <!--Import and render html document-->
        </li>
    </ul>
</template>

<script>
    export default {
        name: "Example",
        data: function () {
            return {
                htmlDocuments: [
                    {
                        id:1,
                        source_url: "/templates/example-1.html"
                    },
                    {
                        id:2,
                        source_url: "/templates/example-3.html"
                    },
                    {
                        id:3,
                        source_url: "/templates/example-3.html"
                    },
                ]

            }
        },


    }
</script>
27 Dec
8 months ago

nolros left a reply on Validation Exception Into A JSON Response

Sorry to be clear. I’m saying that I found the exception handler code in 5.5. release note which works great and as such asking the question as to why it is not included in the current 5.7 build i.e. you still need to add it to the exception handler.

I was getting "message: The given data was invalid" error on standard Vue axios data submission i.e. name and body input text fields.

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ContactForm extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name'      => 'required',
            "body"      => 'required'
        ];
    }

}

Controller example:

public function postContactUs(ContactForm $request)
{
    return ['message' => 'Project Created!'];
}

26 Dec
8 months ago

nolros started a new conversation Validation Exception Into A JSON Response

Any idea why this nugget in 5.5 release notes is not automatically added to the 5.7 install App\Exceptions\Handler class?

without it I kept getting "message: The given data was invalid" on any given Vue AJAX submission

    /**
     * Convert a validation exception into a JSON response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Validation\ValidationException  $exception
     * @return \Illuminate\Http\JsonResponse
     */
    protected function invalidJson($request, ValidationException $exception)
    {
        return response()->json($exception->errors(), $exception->status);
    }
28 Sep
11 months ago

nolros left a reply on Display Same Data On 2 Routes (and Same View) While Keeping DRY

@robot98 you are looking for authorization https://laravel.com/docs/5.7/authorization where you set create policies and authorize users against those policies

26 Sep
11 months ago

nolros left a reply on Select Statement Where $request->input() Laravel 5.5

I think you have named the input it agency_id and not id. Try this -


$agencyarchives = Agencyarchive::select('*')
                        ->where('agency_id', $request->input('agency_id'))
                        ->get();


29 May
1 year ago

nolros left a reply on How Do I Search Records Within The Eager Loaded Data?

@yansusanto here you go

    public function blogPostOfTitle($title, $firstName, $lastName)
    {

        return Blog::where('title', 'LIKE', '%' . $title . '%')
            ->with(['user', function ($q) use ($firstName, $lastName) {
                $q->where('first_name', $firstName);
                $q->where('last_name', $lastName);
            }])
            ->latest()
            ->paginate(10);
    }
        

you also have the option of map but that wouldn't work with pagination

    public function blogPostWithNoPagination($title, $firstName, $lastName)
    {
        return Blog::where('title', 'LIKE', '%' . $title . '%')
               ->with(['user'])
                ->latest()
                ->map(function ($post) use ($firstName, $lastName) {
                    return $post->first_name === $firstName && $post->last_name === $lastName;
                });

    }

nolros left a reply on 404 Not Found In Views Subfolders

@henrylemmon do you have a route for "tasks" in your routes file and do you have a view associated with that route? Suggest you post code for people to review.

nolros left a reply on ReflectionException (-1) Class App\policies\RolePolicy Does Not Exist

@ljlizarraga

have you declared it in the AuthServiceProvider? As a side note when you ReflectionException() it is a often a sign that something is missing in a ServiceProvider() class


<?php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        //
    }
}

nolros left a reply on Get All Collections With BelongsToMany Relation

@rzvme

@Cronix gave you the simplest solution but here are other options

    // credit to Jarek for this
    public function onlyWantRoleNames($id)
    {
        User::find(1)
            ->load(['roles' => function ($q) use ( &$roleNames ) {
                $roleNames = $q->pluck('name','id')->unique();
            }]);

        return $roleNames;
    }

    public function onlyWantRoleNamesOption2()
    {
        $user = User::where("id",1)
            ->with(['roles', function($q) {
                $q->orderBy('name');
            }])->first();

        return $user->roles->pluck('name');

    }

    public function onlyWantRoleNamesOption3($id)
    {
        return User::find($id)
            ->load(['roles' => function ($q)  {
                return $q->pluck('name','id')->unique();
            }]);
    }



  1. Remember when you call find() it has already executed the query so you would need to call load() to reference the relationship if you wanted to query roles post your user query as per my second example.

The Laravel find() method

    /**
     * Execute a query for a single record by ID.
     *
     * @param  int    $id
     * @param  array  $columns
     * @return mixed|static
     */
    public function find($id, $columns = ['*'])
    {
        return $this->where('id', '=', $id)->first($columns);
    }

nolros started a new conversation Import My App Init Vue File

Is the best approach in Vue to import my own init (app or main or whatever you want to call it )

Per the example:

  1. I import the init.vue with import init from './init.vue'
  2. I then init with render: h => h(init)

Question:

Is this a best practice is I didnt want app.js to be more core js file or is there a best practice? Why would I want to do that ?

Why this approach?

Lets say I build multiple mini apps and I want to deploy at a customers site I dont need to screw with their app.js , instead I just load the init / main into their app.js with 2 lines of code and it runs.

JS - init.vue & app.js examples

init.vue

<template>
    <div>
        <p>stuff</p>>
    </div>
</template>

<script>

    export default {

    };

</script>

app.js

require('./bootstrap');

window.Vue = require('vue');

// 1. importing init file
import init from './init.vue'

const app = new Vue({
    el: '#app',
    // 2. rendering / executing it
    render: h => h(init)
});
28 May
1 year ago

nolros left a reply on GET Request $request->getContent() Is Empty

@MrFiliper if I recall you get it as follows:

// no function just key
$var =  $request->key 

which is equal to

echo ($_REQUEST['key']);

///you could also

$var =  $request['key']

Note if it is an API returning XML lets say Pardot then you would parse the curl to xml


$response = new SimpleXMLElement( $pardotApiResponse  );

if ( $response->result) {
       $campaign = $response->result
 }

also worth noting that $name = $request->input('user.name'); only works if e Content-Type header of the request is properly set to application/json

is response coming form an API or form? is a GET or a POST, via curl() or how?

btw, this the request getContent() method.

 /**
     * Returns the request body content.
     *
     * @param bool $asResource If true, a resource will be returned
     *
     * @return string|resource The request body content or a resource to read the body stream
     *
     * @throws \LogicException
     */
    public function getContent($asResource = false)
    {
        $currentContentIsResource = is_resource($this->content);

        if (true === $asResource) {
            if ($currentContentIsResource) {
                rewind($this->content);

                return $this->content;
            }

            // Content passed in parameter (test)
            if (is_string($this->content)) {
                $resource = fopen('php://temp', 'r+');
                fwrite($resource, $this->content);
                rewind($resource);

                return $resource;
            }

            $this->content = false;

            return fopen('php://input', 'rb');
        }

        if ($currentContentIsResource) {
            rewind($this->content);

            return stream_get_contents($this->content);
        }

        if (null === $this->content || false === $this->content) {
            $this->content = file_get_contents('php://input');
        }

        return $this->content;
    }

nolros left a reply on Jquery .text Vs .html

@behnampmdg3 why escape to \n if already in JS. Keep <br> . The script will escape all html tags, style and script except br

Example:

https://codepen.io/matrixme/pen/XYrqOy

HTML

<textarea cols="30" rows="10" id="input"></textarea>
<p><button id="sanitize">Sanitize</button></p>
<p id="output"></p>

JS

(function($) {
    $.sanitize = function(input) {
        var output = input.replace(/<script[^>]*?>.*?<\/script>/gi, '').
                     replace(/<((?!br))[\/\!]*?[^<>]*?>/gi, '').
                     replace(/<style[^>]*?>.*?<\/style>/gi, '').
                     replace(/<![\s\S]*?--[ \t\n\r]*>/gi, '');
        return output;
    };
})(jQuery);


$(function() {
    $('#sanitize').click(function() {
        var $input = $('#input').val();
        $('#output').html($.sanitize($input));
    });

});

nolros left a reply on Jquery .text Vs .html

@behnampmdg3 unsure if you looking 2 way binding or sanitize.

  1. sanitize will stop script tags or any html tags
// HTML
<textarea cols="30" rows="10" id="input"></textarea>
<p><button id="sanitize">Sanitize</button></p>
<p id="output"></p>


JS
(function($) {
    $.sanitize = function(input) {
        var output = input.replace(/<script[^>]*?>.*?<\/script>/gi, '').
                     replace(/<[\/\!]*?[^<>]*?>/gi, '').
                     replace(/<style[^>]*?>.*?<\/style>/gi, '').
                     replace(/<![\s\S]*?--[ \t\n\r]*>/gi, '');
        return output;
    };
})(jQuery);

$(function() {
    $('#sanitize').click(function() {
        var $input = $('#input').val();
        $('#output').text($.sanitize($input));
    });

});

  1. one way binding (jQuery kindof)
//HTML

<p>Type something:</p>
<textarea></textarea>
<p>You typed:</p>
<div id="data"></div>


// JS
var textarea=$("textarea");
var data=$("#data");

textarea.keypress(function() {
    data.text(textarea.val());
});

You can combine the two so you have two sanitized and two way binding

  1. two way binding JS vanilla

// HTML
<input type=text id="myText1">
<span type=text id="myDomElement"></span>


function Binding(b) {
    _this = this
    this.elementBindings = []
    this.value = b.object[b.property]
    this.valueGetter = function(){
        return _this.value;
    }
    this.valueSetter = function(val){
        _this.value = val
        for (var i = 0; i < _this.elementBindings.length; i++) {
            var binding=_this.elementBindings[i]
            binding.element[binding.attribute] = val
        }
    }
    this.addBinding = function(element, attribute, event){
        var binding = {
            element: element,
            attribute: attribute
        }
        if (event){
            element.addEventListener(event, function(event){
                _this.valueSetter(element[attribute]);
            })
            binding.event = event
        }       
        this.elementBindings.push(binding)
        element[attribute] = _this.value
        return _this
    }

    Object.defineProperty(b.object, b.property, {
        get: this.valueGetter,
        set: this.valueSetter
    }); 

    b.object[b.property] = this.value;
}

var obj = {a:123}
var myInputElement1 = document.getElementById("myText1")
var myDOMElement = document.getElementById("myDomElement")

new Binding({
    object: obj,
    property: "a"
})
.addBinding(myInputElement1, "value", "keyup")

.addBinding(myDOMElement, "innerHTML")

obj.a = "Nolan";

nolros left a reply on Eloquent - Timestamps In Pivot Tables

@JarekTkaczyk how are doing sir ? Been a long time. Couldn't you write something like this ? Rough concept have not run or tested it, but wonder if this could be made to work?

class AppServiceProvider
{
    public function boot()
    {

         /**
         * we pass it instance or just date and return new date
         */ 
         Carbon::macro('dateFormater', function ($instance) {
            $dt = Carbon::parse($instance->created_at); 
            
            if (!isset($self) && isset($this)) {
                $self = $this;
            }
  
            return  $dt->format('m-d');
        });


        /**
         * we pass builder callback
         */ 
        Builder::macro('myAppTags', function($callback) {
   
            if (count(call_user_func($callback->bindTo($this)))) {
                foreach ($variable as $key => $value) {
                    variable[$key]['new_date'] = Carbon::macro('dateFormater')
                }
            }
            return $this;
        });

       /**
         * Start here. 
         */ 
        SomeModel::myAppTags(function () {
            return $this->belongsToMany('Tag')->withTimestamps();
        });

    }
}

nolros left a reply on A Way To Store Site Settings In Laravel

@chori.av 4 Options, are as follows:

Option 1 - traditional method would be settings DB a "settings" table with columns for each setting (doesn't scale well and would definitely NOT recommend)

list of table columns (+1 column for every type of setting)

id: 
is_business: boolean
has_fax: boolean
server: ...

Option 2. DB with 2 tables:

Table 1. setting_prop (options) e.g. is business or has business related to business, but you might have settings like, has_fax, is_local, etc.

id: 3
prop_key: is_business
prop_value: true

id: 4
prop_key: is_business
prop_value: false

Unlike #1 ... you have to search for the key and then read values e.g. (where->("prop_key","is_business")->get()) => in our case we get 2 records back

Table 3: user to setting property relationship (pivot table) - user_id , setting_prop_id e.g. user 1 has selected is_business as false

Option 2. - (My preferred method) json string stored in SQL 5.7 json column or < SQL 5.7 text column. In this case you are parsing the json string to set and get values. So more code than DB approach. Very flexible as you can adjust as you need. Could encrypt string if there is sensitive data contained. Also works great with multi-language as you can create your own language file to support all languages. So each admin will have a record / row. Columns:

 id: int
settings: json / text
timestamp: timestamp  

Option 3. if performance is key you could store as bits. That does require more coding and easy t get confused. Unless you have a large app and high transactions wouldn't recommend.

Example of json once parsed to array

<?php

use App\User;

class Settings
{

    /**
     * @var array
     */
    protected $settings = [];

    /**
     * @var User
     */
    protected $user;

    /**
     * @var array
     */
    protected $defaults = [
        'opt_in_monthly' => false,
        'opt_in_partner' => false,
    ];

    /**
     * Settings constructor.
     * @param array $settings
     * @param User $user
     */
    public function __construct(array $settings, User $user)
    {
        $this->user = $user;
        $this->settings = $settings;
    }

    /**
     * Get setting by key
     *
     * @param $key
     * @return mixed
     */
    public function get($key)
    {
        return array_get($this->settings, $key);
    }

    /**
     * Return true if settings has key
     *
     * @param $key
     * @return bool
     */
    public function has($key)
    {
        return array_key_exists($key,$this->settings);
    }

    /**
     * Set default settings for user
     */
    public function defaults()
    {
        foreach ($this->defaults as $key => $value) {
            $this->user->set($key, $value);
        }
    }

    /**
     * Set setting key value pair
     *
     * @param $key
     * @param $value
     */
    public function set($key, $value)
    {
        $this->settings[$key] = $value;

        $this->persist();
    }

    /**
     * Return all settings
     *
     * @return array
     */
    public function all()
    {
        return $this->settings;
    }

    /**
     * Merge setting attributes with existing attributes
     *
     * @param array $attributes
     * @return bool|int
     */
    public function merge(array $attributes)
    {
        $this->settings = array_merge(
            $this->settings,
            array_only($attributes, array_keys($this->settings))

        );

        return $this->persist();
    }

    /**
     * Save settings
     *
     * @return bool|int
     */
    public function persist()
    {
       return $this->user->update(['settings' => $this->settings]);
    }

    /**
     * Magic get for settings by key
     *
     * @param $key
     * @return mixed
     * @throws \Exception
     */
    public function __get($key)
    {
        if ($this->has($key)) {
            return $this->get($key);
        }

        throw new \Exception("The {$key} setting does not exist.");
    }


}
26 May
1 year ago

nolros left a reply on Are There Any Security Concerns About Updating The Page This Way?

@Snapey not to labor the point but I disagree. If the client is a hacker and you open a door then your backend is also vulnerable. I can could inject DB. If I dont sanitize then I could inject something like into input field [Gotach](javascript&#58this;alert(1&#41)) Gotach and I now start from there onwards. I think client is as important as server. Jeffery escapes the input, but if he didn't this would execute JS inside of his site and away we go. I create a Laravel account. I curl into the site. I use curling to walk up the directory, find routes or whatever. I execute JS to inject SQL in add item as an example. I mean there are 100 things that could stop me fro doing this, but my 2 cents is client is important. Sorry to labor the point.

nolros left a reply on $this->request->get() Doesn't Work Inside FormRequest

@LorienDarenya as @Snapey said your extending FormRequest which extends Request so all you need is $this->get() as $this === request() in this class

nolros left a reply on Are There Any Security Concerns About Updating The Page This Way?

@Cronix why do you say no as a matter of interest? Given that there is no safe or sanitized html? Example, "sender" var could be changed to inject something in the HTML, for example, if update_text is updated to DB you can inject SQL crap. AngularjS for example wont be happy with that and will require some sort of bind-unsafe-html directive or $sce, etc. A I missing something?

nolros left a reply on AngularJS - Factory Array From Controller

@jcmargentina

The User API could be extracted to UserServices and ApiServices, but if I were actually writing an app I would build an APIProvider. If I were building a large app I would break it into Ap provideri, Http Endpoints, request service, url resolver, etc. services. However, to simplify here is an example

I have not tested or run the code, but here is how I would do it

  1. Blade example
<div class="article__col column--50"
     ng-controller="UserController as UserCtrl">
    <ul>
        <li ng-click="UserCtrl.setActive(user,$event)"
            ng-repeat="user in UserCtrl.data.users.data track by user.id">
                <p ng-bind="user.first_name"></p>
        </li>
    </ul>
</div>
  1. AngularJS example.
(function () {
    'use strict';


    UsersApi.$inject = ['$http', "$q", "_ROUTES", "$window"];
    function UsersApi($http,$q, _ROUTES, $window) {
        var service = this,
            token = $window.localStorage["_token"] || defaultValue;

        /**
         * API Resource instance. Needed if grow API to include http endpoints etc.
         */
        function Resource(resource) {
            this.resource = resource;
        }

        /**
         * api service as you will need api.get, api.save, etc
         */
        let api = function apiService(resource) {
            return new Resource(resource);
        };

        /**
         * Get on a given url
         *
         * @param url
         * @param params
         */
        api.get = function apiGet(url, params) {
            return http({
                method: 'GET',
                url: url,
                params: params // check for params
            });
        };

        function isOK(response) {
            function isErrData(data) {
                return data && data._status && data._status === 'ERR';
            }
            return response.status >= 200 && response.status < 300 && !isErrData(response.data);
        }


        /**
         * Call $http once url is resolved
         */
        function http(config) {
            return $q.when(config.url)
                .then(function(url) {
                    config.url = url;
                    return $http(config);
                }).then(function(response) {
                    return isOK(response) ? response.data : $q.reject(response);
                });
        }

        function hasUserRoute(url) {
            // can do further validation regex or string etc
            return (angular.isUndefined(url) ?_ROUTES.USERS : url) + token;
        }

        /**
         *Get all users of api url
         */
        service._getUsers = function (url, params = {}) {
            return api.get(hasUserRoute(url), params)
                .then(function (result) {
                    return result;
                });
        };

        return {
            getUsers: function (url, params) {
                return service._getUsers(url, params);
            }

        }
    }

    UserController.$inject = ['$scope','UsersApi'];
    function UserController($scope,UsersApi) {
        let vm = this,
  
            getAllUsers = function () {
                UsersApi
                    .getUsers()
                    .then(function (results) {
                        // you would do data and error validation here as well. For brevity sake ill let you handle
            // this is now used in blade or html
                        vm.data = {
                            users: results,
                        };
                    });
            };



        vm.$onInit = function () {
         // note: not good practice because there is no url or params being passed but just an example. The right way would be based on a method you would resolve url to a server and return the url to pass through to http method, but lets use as example

            getAllUsers();
        };
    }


    angular.module('myapp')
        .factory('UsersApi', UsersApi)
        .controller('UserController', UserController)
        .constant("_ROUTES", {
            USERS: 'http://localhost:8000/api/user/list?token=',
        })

})();

nolros left a reply on Best Strategy To Model This?

@jcmargentina

Note: i would think you dont really need school / store, etc. as you could just have organization and use some field to indicate it is a school , etc use organization_properties model / table to create dynamic properties that way it scales to any org type.

Here are some options to explore:

Option 1: use SQL join

Option 2: use hasManyThrough .

class Organization extends Model
{
    public function roles()
    {
        return $this->hasManyThrough(
            'App\Roles',
            'App\User',
            'organization_id', // Foreign key on users table...
            'user_id', // Foreign key on roles table...
            'id', // Local key on organization table...
            'id' // Local key on users table...
        );
    }

    public function schools()
    {
    return $this->hasMany('App\School');
    }

    public function stores()
    {
    return $this->hasMany('App\Store');
    }

}

class School extends Model
{
    public function organizations()
    {
       // foreign key organization_id
    return $this->belongsTo('App\Organization')
    }
}

class Store extends Model
{
    public function organizations()
    {
       // foreign key organization_id
    return $this->belongsTo('App\Organization')
    }
}

Option 3: Polymorphic

Relationship between roles and user and roles and org ... this has potential issues but workable

class Roles extends Model
{
    public function roleable()
    {
        return $this->morphTo();
    }
}

class User extends Model
{
    public function role()
    {
        return $this->morphMany('App\Role', 'roleable');
    }
}

class Organization extends Model
{
    public function role()
    {
        return $this->morphMany('App\Role', 'roleable');
    }
}
04 Feb
1 year ago

nolros left a reply on How To Get Random Array

if you re attempting to get random model / table data you could do something like this:


         $user = User::orderBy(\DB::raw('RAND()'))->first();

nolros left a reply on How Does Laravel Check Login Info With Database?

Im not sure what you asking? Have you made auth? Migrated databased? if youv'e run php artisan auth:make then laravel will use app\http\controller\auth\LoginController as the controller and trait AuthenticatesUsers on that controller does most of the work

nolros left a reply on Logout Gives Methodnotallowedexception

  1. Do a php artisan route:list to see if you have conflicts
  2. is the logout redirect sending you to a route with a conflicting method. In the LoginController you have trait called AuthenticatesUsers with the method below that will redirect you somewhere. Do you have a default or alt route?
    /**
     * Log the user out of the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function logout(Request $request)
    {
        $this->guard()->logout();

        $request->session()->invalidate();

        return redirect('/');
    }
03 Feb
1 year ago

nolros started a new conversation L5.5 Bind Model & Service In Service Provider

My service provider below ProductsServiceProvider works. I register a service class UrlService(…) and then inject the UrlService along with a Product Model into a Product repository ProductRepository(…). Both are bound to interfaces.

My questions:

  1. Should the UrlService be bound to an interface UrlInterface ?

Is it best practice to bind a service to an interface or should I just register the actual class as a service and inject the actual class itself UrlService::class i.e. NO bound interface?

  1. Should the UrlService be registered as singleton $app->singletion('service', ...).?

Should the UrlService be registered as singleton given its purpose will be to provide dynamic data based on unqiue url / uri's ? Or should I resgiter it $app->bind('service', ...); ?

  1. Should the ProductRepository be registered as singleton $app->singletion('service', ...).?

As im injecting both a Product model and the UrlService into a Product Repository should repository also be seen as a service and as such a singleton and again should I bind it an interface?

namespace Providers;

        use Illuminate\Support\ServiceProvider;
        use Products\Models\Product;
        use Products\ProductRepository;
        use Products\ProductInterface;
        use Resources\UrlService;
        use Resources\UrlInterface;


        class ProductsServiceProvider extends ServiceProvider
        {

            /**
             * Indicates if loading of the provider is deferred.
             *
             * @var bool
             */
            protected $defer = true;

            /**
             * Bootstrap the application services.
             *
             * @return void
             */
            public function boot()
            {
                //
            }

            /**
             * Register the application services.
             *
             * @return void
             */
            public function register()
            {
                $this->registerUrlService();
                $this->registerSolutionRepository();
            }

            /**
             * Register a url service 
             */
            protected function registerUrlService()
            {
                $this->app->singletion(UrlInterface::class, function ($app) {
                    return new UrlService($app['request'], config('models.url-configl') );
                });
            }

            /**
             * register a product repository and inject products and url service
             */
            protected function registerProductRepository()
            {
                $this->app->singletion(ProductInterface::class, function($app) {

                    $solution = $this->app->make(Product::class);
                    $urlService = $this->app->make(UrlInterface::class);

                    return new ProductRepository($solution, $urlService );
                });
            }

        }

01 Oct
1 year ago

nolros left a reply on Page Load In Laravel Quite Slow

Also if you really looking for performance you might look at lumen which is for a lack of better term - Laravel lite.

nolros left a reply on A Real Example Of Angular 4, Laravel 5.5 And Elixir

@IsaacBen thanks for reply. I used Angular 1.x exclusively with Laravel and although both MVC frameworks there were many scenarios where complemented each other well. The problem AJS4 is that is very much an overlap of Laravel, but skilling up on Vue or React is a pain. I can get the two to work together it just is not clean therefore wondering if there are any solid examples.

30 Sep
1 year ago

nolros started a new conversation A Real Example Of Angular 4, Laravel 5.5 And Elixir

Anyone have a real example of Laravel 5.5, Angular 4 and Elixir working together. All the examples I’ve seen install all typescript config files into root. Some use NPM and some use gulp. It is just ugly. Even when I get it to install into storage it copies all npm modules into storage. Im sure there are ways to config it so the two work together? There must be a best practice out there to get the two to work together?

If not I’m going to have to move to Vue or React which blows.

Sidenote: I even bought the Angular 4 and Laravel 5 book. What a piece of crap. Don’t waste a cent.

29 Apr
2 years ago

nolros left a reply on Eloquent's Join

@Sreadon here is your answer:

  1. Migration creates

       Schema::create('items', function(Blueprint $table) {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->unsignedInteger('post_id')->unique()->index();
            $table->string('name', 100);
            $table->string('category', 100);
            $table->timestamps();
        });

        Schema::create('item_details', function(Blueprint $table) {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->unsignedInteger('item_id')->unique()->index();
            $table->text('description');
            $table->timestamps();
        });

        Schema::create('item_games', function(Blueprint $table) {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->unsignedInteger('item_id')->unique()->index();
            $table->text('description');
            $table->timestamps();
        });

  1. Model and controller example

2.1. Use Singular naming convention when creating models as each model instance will be a single item e.g. Item, itemDetail. DB tables would be plural as it contains many items

2.2. ->hasOne and ->belongsTo will Define a one-to-one or many relationship and as such will return a single instance so again name them accordingly.

In short you only need this syntax with relations inside of your item model:

     /**
         * @param $id
         * @return mixed
         */
        public function getItem($id)
        {
            return $this
                ->where('item_id', $id)
                ->with(['itemDetail', 'games'])
                ->first();
        }

Also note that your original syntax would work

** DETAIL WITH LOTS OF EXAMPLES**


     class HomeController extends Controller
    {
        /**
         * @var Item
         */
        private $item;

        /**
         * HomeController constructor.
         * @param Item $item
         */
        public function __construct(Item $item)
        {
            $this->item = $item;
        }


        /**
         * @return $this|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
         */
        public function index()
        {

            if ($item = $this->item->getItem(1) ) {
                
                $exampleRelations = [
                    'game' => $item->game->description,
                    'detail' => $item->itemDetail->description,
                ];
                
                return view('itemView')->with(['item' => $item, 'descriptions' => $exampleRelations]);
            }

            return view('itemErrorView');

        }

        public function getGame($gameId)
        {
            $item = $this->item->find(1);

            $game = $item->getGame($gameId);

//            OR 
            
            $item = $this->item->find(1)->getGame($gameId);

        }
        
    }

    class Item extends Model
    {
        /**
         * @var string
         */
        protected $table = 'items';

        /**
         * @var string
         */
        protected $primaryKey = 'id';

        /**
         * @return \Illuminate\Database\Eloquent\Relations\HasOne
         */
        public function itemDetail()
        {
            return $this->hasOne(ItemsDetail::class);
        }

        /**
         * @return \Illuminate\Database\Eloquent\Relations\HasMany
         */
        public function games()
        {
            return $this->hasMany(ItemGame::class);
        }

        /**
         * @param $id
         * @return mixed
         */
        public function getItem($id)
        {
            return $this
                ->where('item_id', $id)
                ->with(['itemDetail', 'games'])
                ->first();
        }

        /**
         * Purely for illustrative purposes where Im query a specific game 
         * @param $id
         * @return mixed
         */
        public function getGameOfItem($id,$gameId)
        {
            return $this
                ->where('item_id', $id)
                ->with(['itemDetail', 'games' => function($query) use ($gameId) {
                    $query->where('id', $gameId);
                }])
                ->first();
        }

        /**
         * Use the relationship to query a game
         * 
         * @param $gameId
         * @return mixed
         */
        public function getGame($gameId)
        {

          // NOTE: $item->game->description IS NOT THE SAME AS $item->game()->description  - the first will work the 2nd will fail as description is not a method on ItemGame model whereas description is a property on the instance of ItemGame


            return $this
                ->game()
                ->where('id', $gameId)
                ->first();
        }


    }



    class ItemDetail extends Model
    {
        /**
         * @var string
         */
        protected $table = 'item_details';

        /**
         * @var string
         */
        protected $primaryKey = 'id';

        /**
         * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
         */
    public function Item()
    {
        return $this->belongsTo(Item::class);
    }

    }

    class ItemGame extends Model
    {
        /**
         * @var string
         */
        protected $table = 'item_games';

        /**
         * @var string
         */
        protected $primaryKey = 'id';

        /**
         * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
         */
        public function Item()
        {
            return $this->belongsTo(Item::class);
        }


    }






nolros left a reply on Issues When Cloning A Project From Github

@CHRIS1904 sounds like your migration table is corrupt or you have drop issue with settings. Im assuming this is not production? If so you could do the following:

  1. try reset 

  php artisan migrate:reset
  // If it wont allow you to reset because of the  settings table then

  2. delete the migration table then run 

  php artisan migrate:install 

  3. if this works then I tend 
    
     php artisan migrate:reset (rollback all)
     // 3.1 delete migration table again
     composer dumpautoload
     php artisan config:clear
     php artisan migrate:install 
    // (btw php artisan migrate will create teh DB if it doesnt exist but I prefer to go through the steps)
     php artisan migrate

    4. If the problem persists then you have an issue in one of your migrations in which case fix and repeat the above until problem resolved

nolros left a reply on Laravel 5.4 Routing And Anchor Tags

use this syntax in view blade / HTML


     <a href="{!! url()->current() !!}">Current path</a>
OR
     <a href="{!! url()->full() !!}">Full path</a>
OR
     <a href="{!! url('/books/news') !!}">Relative to root path</a>

OUTSIDE EXAMPLE:
OR
     <a href="{!! url('http://www.google.com') !!}">Path to google</a>

btw there is no required relation with route and view e.g.

  Route::get('/books', function () { 
      // example will be the subdirectory under views and examplebook will be the blade view 'examplebook.blade.php'
     return view('example.examplebook'); 
  });

27 Apr
2 years ago

nolros left a reply on Trying To Get Property Of Non-object (View: /var/www/html/pet/resources/views/backend/product/product-library.blade.php)

@Ahmedjalal try the following :

      public function index() 
      { 

            $products = Product::with('categories', 'colors' , 'sizes', 'materials', 'fantasias')->get(); 

            return view('backend.product.product-library')->with(['products' => $products]); 
      }