Laravel 5 search in a JSON file and show data - php

I have a search engine with typeahead. What I want is that after doing a search and giving the submit, show the results. This gives two problems: first it returns an empty array and second, it does not allow me to access the properties telling me it is not an object.
In controller, I used collect() to allow me to access the properties, but it does not work and WHERE either.
public function store(Request $request)
{
$url = 'storage/json/es/noticia.json';
$datos = file_get_contents($url);
$data = json_decode($datos, true);
$data = collect($data)->where("title","LIKE","%{$request->texto}%")->all();
return view('web.buscar.index', compact('data'));
}
If I use $data = collect($data)->all(); I can see the collection:
array:8 [▼
0 => []
1 => array:4 [▼
"id" => 2
"title" => "There is a title"
"lead" => "There is a lead"
"slug" => "there-is-a-title"
]
2 => array:4 [▶]
3 => array:4 [▶]
4 => array:4 [▶]
5 => array:4 [▶]
6 => array:4 [▶]
7 => array:4 [▶]
]
Then If I try: $value->title in the view I have the error: Trying to get property 'title' of non-object. In the view I have:
{!! Form::open([
'route' => 'buscar',
'id' => 'buscar',
'name' => 'buscar',
'class' => 'buscador col-xs-12',
'method' => 'POST',
'accept-charset' => 'utf-8'
]) !!}
<input id="texto" name="texto" class="input_buscador typetitulo" autocomplete="off" type="text"/>
{!! HTML::image('images/web/icons/lupa.svg', '', array('height' => '30', 'class' => 'boton_buscador', 'onclick' => 'document.buscar.submit()') ) !!}
{!! Form::close() !!}
#if(isset($data))
#foreach($data as $value)
<span>{{$value->title}}</span><br>
#endforeach
#endif
If I use $data = collect($data)->pluck('title'); in the controller and in the view I don't call the property 'title', this works, but it's not what I want because I need to access other properties too.
Any idea? Thanks in advance!

This is failing because the first array in your array does not have any values, so you will get undefined index, remove any empty arrays by doing
public function store(Request $request)
{
$url = 'storage/json/es/noticia.json';
$datos = file_get_contents($url);
$data = json_decode($datos, true);
$data = array_filter($data);
$data = collect($data)->where("title","LIKE","%{$request->texto}%")->all();
return view('web.buscar.index', compact('data'));
}
Or you can test to see if it is there in your foreach
#foreach($data as $value)
<span>{{$value->title ?? ''}}</span><br>
#endforeach
You can then search the collection using a filter
collect($data)->filter(function ($item) use ($request) {
return $item->title == $request->texto;
)
You can edit the return to be more granular using stristr etc

Related

Laravel 8.12 does not show error messages

I don't understand why the error message is not displayed in form control with laravel. What is my error?
While I could get the "okey" message when I fulfill the conditions below, I could not clearly understand that the error message was not displayed because it did not meet the conditions.
"Information Is Beautiful When It Is Shared."
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Website\contact;
Route::get('/register', [contact::class, 'index'])->name('register');
Route::post('/register-submit', [contact::class, 'post'])->name('register.post');
contact.php
<?php
namespace App\Http\Controllers\Website;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class contact extends Controller
{
public function index()
{
return view('Website.contact');
}
public function post(Request $request)
{
$request->validate([
'name' => ['required', 'max:10'],
'email' => ['required'],
]);
echo "okey";
}
}
contact.blade.php
<div class="container pt-lg-5">
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<form method="post" action="{{route('register.post')}}">
#csrf
<div class="form-group">
<label for="exampleInputEmail1">name</label>
<input type="text" class="form-control" name="name">
</div>
<div class="form-group">
<label for="exampleInputPassword1">E-mail</label>
<input type="email" class="form-control" name="email">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
Illuminate\Validation\Validator {#258 ▼
#translator: Illuminate\Translation\Translator {#255 ▶}
#container: Illuminate\Foundation\Application {#2 ▶}
#presenceVerifier: Illuminate\Validation\DatabasePresenceVerifier {#259 ▶}
#failedRules: array:2 [▼
"name" => array:1 [▼
"Required" => []
]
"email" => array:1 [▼
"Required" => []
]
]
#excludeAttributes: []
#messages: Illuminate\Support\MessageBag {#261 ▼
#messages: array:2 [▼
"name" => array:1 [▼
0 => "The name field is required."
]
"email" => array:1 [▼
0 => "The email field is required."
]
]
#format: ":message"
}
#data: array:3 [▶]
#initialRules: array:2 [▶]
#rules: array:2 [▼
"name" => array:2 [▼
0 => "required"
1 => "max:10"
]
"email" => array:1 [▼
0 => "required"
]
]
#currentRule: "required"
#implicitAttributes: []
#implicitAttributesFormatter: null
#distinctValues: []
#after: []
+customMessages: []
+fallbackMessages: []
+customAttributes: []
+customValues: []
+extensions: []
+replacers: []
#fileRules: array:9 [▼
0 => "Between"
1 => "Dimensions"
2 => "File"
3 => "Image"
4 => "Max"
5 => "Mimes"
6 => "Mimetypes"
7 => "Min"
8 => "Size"
]
#implicitRules: array:10 [▶]
#dependentRules: array:21 [▼
0 => "After"
1 => "AfterOrEqual"
2 => "Before"
3 => "BeforeOrEqual"
4 => "Confirmed"
5 => "Different"
6 => "ExcludeIf"
7 => "ExcludeUnless"
8 => "ExcludeWithout"
9 => "Gt"
10 => "Gte"
11 => "Lt"
12 => "Lte"
13 => "RequiredIf"
14 => "RequiredUnless"
15 => "RequiredWith"
16 => "RequiredWithAll"
17 => "RequiredWithout"
18 => "RequiredWithoutAll"
19 => "Same"
20 => "Unique"
]
#excludeRules: array:3 [▼
0 => "ExcludeIf"
1 => "ExcludeUnless"
2 => "ExcludeWithout"
]
#sizeRules: array:8 [▼
0 => "Size"
1 => "Between"
2 => "Min"
3 => "Max"
4 => "Gt"
5 => "Lt"
6 => "Gte"
7 => "Lte"
]
#numericRules: array:2 [▼
0 => "Numeric"
1 => "Integer"
]
#dotPlaceholder: "YEdPXjrZ4cLZZ3wV"
}
If you are willing for another way to solve your problem, or a quick solution you can always use Validator class directly,
First add this to your controller,
use Illuminate\Support\Facades\Validator;
Then,
public function post(Request $request)
{
$validator = Validator::make($request->all(),[
'name' => ['required', 'max:10'],
'email' => ['required'],
]);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator);
}
echo "okey";
}
In my case I solved it by removing \Illuminate\Session\Middleware\ StartSession::class from 'middleware' in Kernel.php, leaving it in the 'web' group in the same file.
go on kernal.php and find web route and removed \Illuminate\Session\Middleware\StartSession::class,
then check all validation working fine

"Property [role] does not exist on this collection instance."

I have a method that checks if a role is equal to 1 and then sends back some data. The method looks like so:
if($user->role == 1) {
$dmca = Dmca::get()->take(5);
$data = [
'status' => 200,
'data' => $dmca
];
return response($data);
} else {
$dmca = Dmca::where('client', $request->user_id)->get()->take(5);
$data = [
'status' => 200,
'data' => $dmca
];
return response($data);
}
}
On the dump and die of the $user instance, you can see the role is there and is set. But on return, I get the error
#attributes: array:11 [
"id" => 1
"name" => null
"email" => "Grahammorbydev#gmail.com"
"model_name" => "man"
"subscribed" => 0
"email_verified_at" => null
"password" => "$2y$10$yy1Yj.GGez7efEdFdkjaf.RlQS17Zc7QYUANz3RvdE00fVm0f9AYq"
"role" => 1
"remember_token" => null
"created_at" => "2020-07-05 17:54:38"
"updated_at" => "2020-07-05 17:54:38"
]
Getting the following error when the axios returns
"Property [role] does not exist on this collection instance."
As the error message is shown
"Property [role] does not exist on this collection instance."
It indicates that $user is an instance of Collection
You have to change
$user = User::where('id', $request->user_id)->get();
To this
$user = User::where('id', $request->user_id)->first();
get() : returns a collection of models matching the query.
first() : returns the first record found in the database. If no matching model exist, it returns null.
more info

Call to a member function links() on array in Laravel 5.6

I am using pagination in Laravel 5.6 to build an application. I am using Laravel DB instead of Eloquent. However, when I add a pagination link on view, it shows an error Call to a member function links() on array. This is because I am using an array, the default is an object with a collection. The output I am getting looks like
array:12 [▼
"current_page" => 1
"data" => array:3 [▶]
"first_page_url" => "http://127.0.0.1:8000/posts?page=1"
"from" => 1
"last_page" => 3
"last_page_url" => "http://127.0.0.1:8000/posts?page=3"
"next_page_url" => "http://127.0.0.1:8000/posts?page=2"
"path" => "http://127.0.0.1:8000/posts"
"per_page" => 3
"prev_page_url" => null
"to" => 3
"total" => 9
]
When I use normal pagination i.e. without converting to an array, the output is
LengthAwarePaginator {#264 ▼
#total: 9
#lastPage: 3
#items: Collection {#251 ▶}
#perPage: 3
#currentPage: 1
#path: "http://127.0.0.1:8000/posts"
#query: []
#fragment: null
#pageName: "page"
}
The problem I face here is adding other data to collection
I can't use the default output return by pagination() method. Can someone please suggest how to solve this issue?
Using the below, I am getting the required output.
Step 1: Include LengthAwarePaginator in the file
use Illuminate\Pagination\LengthAwarePaginator;
Step 2: Create an object of LengthAwarePaginator
$paginate = new LengthAwarePaginator(Array, countOfArray, perPage, currentPage, [
'path' => request()->url(),
'query' => request()->query()
]);
I kept currentPage value as null.
Return $paginate to view.
return view('home', ['data' => Array, 'page' => $paginate]);

replace a key value in array with a new value

I have a form with this fields in laravel:
<form>
<input type='text' name="title">
<input type='file' name="files">
</form>
In server side, I done some proccess on files.
$imagesUrl = $this->uploadImages($request->file('files'));
dd($imagesUrl):
array:2 [▼
"images" => array:4 [▼
"original" => "/upload/images/2017/10453717_202487510125261_45876946_n.jpg"
300 => "/upload/images/2017/300_10453717_202487510125261_45876946_n.jpg"
600 => "/upload/images/2017/600_10453717_202487510125261_45876946_n.jpg"
900 => "/upload/images/2017/900_10453717_202487510125261_45876946_n.jpg"
]
"thumb" => "/upload/images/2017/300_10453717_202487510125261_45876946_n.jpg"
]
Now I want replace $imagesUrl with $request->file('files') and insert new record in database.
I try this:
auth()->user()->article()->create(array_merge($request->all() , [ 'files' => $imagesUrl]));
But I get this error:
(1/1) ErrorException Array to string conversion
what is my wrong?
Answer: I added this code in modal
protected $casts = [
'files' => 'array'
];
You should try this:
$imagesUrl = serialize($imagesUrl);
$arrInsert = ['title'=> $request->title,'files'=>$imagesUrl];
auth()->user()->article()->create($arrInsert);
and retrieve it again and then unserialize
$imagesUrl = unserialize($raw->files);

Laravel htmlentities() expects parameter 1 to be string, array given

I'm trying to use https://github.com/skmetaly/laravel-twitch-restful-api package to get twitch integration to my website.
That's the error that i get.
ErrorException in helpers.php line 469:
htmlentities() expects parameter 1 to be string, array given (View: /var/www/rafdev.ovh/html/msvixen/resources/views/twitch.blade.php)
My controller
$code = Input::get('code');
if ($code !== null)
{
$token = TwitchApi::requestToken($code);
} else
{
$token = null;
}
$data = TwitchApi::streamsFollowed($token);
return view('twitch', ['token' => $token, 'data' => $data]);
my view
#extends('master')
#section('content')
<h1>Twitch.TV</h1>
{{ $token }}
{{ $data }}
#endsection
After using dd()
array:9 [▼
0 => array:11 [▼
"_id" => 17733016640
"game" => "World of Warcraft"
"viewers" => 15551
"created_at" => "2015-11-15T22:27:13Z"
"video_height" => 1080
"average_fps" => 60.2769481401
"delay" => 0
"is_playlist" => false
"_links" => array:1 [▶]
"preview" => array:4 [▶]
"channel" => array:22 [▶]
]
1 => array:11 [▶]
2 => array:11 [▶]
3 => array:11 [▶]
4 => array:11 [▶]
5 => array:11 [▶]
6 => array:11 [▶]
7 => array:11 [▶]
8 => array:11 [▶]
]
so it works, but when i try to display data - its back to the htmlentities() error
This is happening because $data is returned as an array.
When TwitchApi::streamsFollowed($token); is called, the Facade calls the method in Skmetaly\TwitchApi\Services\TwitchApiService.
This in turn creates an instance of Skmetaly\TwitchApi\API\Users and calls the streamsFollowed() method there.
This method makes a call to /streams/followed which returns a data set such as the example below. It's automatically converted to an array rather than JSON using the Guzzle HTTP Client's json() method.
{
"_links": {
"self": "https://api.twitch.tv/kraken/streams/followed?limit=25&offset=0",
"next": "https://api.twitch.tv/kraken/streams/followed?limit=25&offset=25"
},
"_total": 123,
"streams": [...]
}
In order to display the streams you'd need to iterate over the streams array within $data.
If you were to modify your controller slightly
return view('twitch', ['token' => $token, 'streams' => $data->streams]);
You'd then be able to iterate over the streams in your view.
#foreach($streams as $stream)
{{ $stream }}
#endforeach
Update: You'll notice that each stream is also an array. What this means is you need to choose which of the keys in each array you'd like to display. Let's assume that inside one of the streams there is a key called broadcaster which contains a string; you could modify the above as follows.
#foreach($streams as $stream)
{{ $stream['broadcaster'] }}
#endforeach
Having now read the streams example response documentation it would appear that the contents of a stream varies depending on whether or not the stream is online. NB: This is assuming the data structure is the same as you've not posted the contents of a stream in your question.
This means that offline, {{ $stream['broadcaster'] }} would work, but when online it wouldn't and you'd get the same error. What you'll likely need to do is use an #if #else block in your #foreach to determine if the stream is null before trying to echo part of the information.
You could also filter the offline streams in the controller by removing null values from data.

Categories