I'm in a difficult situation. I'm building a birthlist clone with a scraper but it's difficult to code it because I'm not that experienced. I've managed to create an admin page with multiple forms to insert websites, categories and a link form where you can specify on what link the scraping should be done and to what site and category it will be linked. However, adding such things is no problem, but deleting them is not working..
My sites, categories en links are displayed on my admin page with for each element a scrape and delete button. When I delete the last item in the row, it deletes the first element. When I want to delete something else, laravel throws an exception that it tries to attempt to read property on null, which means that it no longer exists. When I dump and die before the delete function, every item in every list has the id '1'. That is why it deletes the first item in a row. Can anyone help me please?
I assume it's because the id that is requested to delete the item, is retrieved from the url and the id that is given in the url is the user id which is 1. So if anyone can give me tips to make sure I can give the id of the user but in a different way. Let me know! My code:
Admincontroller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Website;
use App\Models\Category;
use App\Models\Link;
use Goutte\Client;
class AdminController extends Controller
{
public function showAdmin($id)
{
$categories = Category::all();
$websites = Website::all();
$links = Link::all();
return view('admin', compact('categories', 'websites', 'links'));
}
public function storeWeb(Request $request)
{
$web = Website::create([
'title' => $request->input('site'),
'url' => $request->input('url')
]);
return back();
}
public function destroyWeb(Request $request, $id)
{
$web = Website::find($id);
$web->delete();
return back();
}
public function storeCat(Request $request)
{
$cat = Category::create([
'title' => $request->input('title')
]);
return back();
}
public function destroyCat(Request $request, $id)
{
$cat = Category::find($id)->first();
$cat->delete();
return back();
}
public function storeLink(Request $request)
{
$link = Link::create([
'url' => $request->input('scrapeUrl'),
'main_filter_selector' => $request->input('filter'),
'website_id' => $request->input('website_id'),
'category_id' => $request->input('category_id'),
]);
return back();
}
public function destroyLink(Request $request, $id)
{
$link = Link::find($id);
dd($link);
$link->delete();
return back();
}
public function scrape(Request $request)
{
$link = Link::find($request->link_id);
$scraper = new Scraper (new Client());
$scraper->handle($link);
if($scraper->status == 1) {
return response()->json(['status' => 1, 'msg' => 'Scraping done']);
} else {
return response()->json(['status' => 2, 'msg' => $scraper->status]);
};
}
}
My adminpage:
<body >
@include('partials.header')
<main >
<div >
<h2>Welkom <strong>{{ auth()->user()->name }}</strong></h2>
</div>
<div >
<div >
<h3 ><strong>Winkels</strong></h3>
<div >
<div >
<form action="{{ route('newWeb', Auth()->user()) }}" method="POST">
@csrf
<div >
<label for="shop" >Webshop:</label>
<input type="text" required name="site" id="titel" placeholder="Dreambaby">
</div>
<div >
<label for="url" >
Voeg een url toe:
</label>
<input type="url" required name="url" id="url" placeholder="http://dreambaby.com/">
<button name="shop" value="add" type="submit">Voeg link toe</button>
</div>
</form>
<div >
<div >
<table >
@foreach ($websites as $web)
<form action="{{ route('delWeb', Auth()->user()) }}" method="POST">
@csrf
@method('DELETE')
<tr >
<td >{{ $web->title }}</td>
<td >{{ $web->id }}</td>
<td ><button type="submit">Verwijderen</button>
</td>
</tr>
</form>
@endforeach
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div >
<div >
<h3 ><strong>Categorieën</strong></h3>
<div >
<div >
<form action="{{ route('newCat', Auth()->user()) }}" method="POST">
@csrf
<div >
<label for="url" >
Voeg een categorie toe:
</label>
<input type="text" required name="title" id="cat" placeholder="Eten en Drinken">
<button name="category_submit" type="submit">toevoegen</button>
</div>
</form>
<div >
<div >
<table >
@foreach ($categories as $category)
<form action="{{ route('delCat', Auth()->user()), $category->id }}" id="{{ $category->id }}" method="POST">
@csrf
@method('DELETE')
<tr >
<td >{{ $category->title }}</td>
<td >{{ $category->id }}</td>
<td ><button type="submit">Verwijderen</button>
</td>
</tr>
</form>
@endforeach
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div >
<div >
<h3 ><strong>Scrapes</strong></h3>
<div >
<div >
<form action="{{ route('newLink', Auth()->user()) }}" method="POST">
@csrf
<div >
<label for="scrape" >Url:</label>
<input type="text" required name="scrapeUrl" id="scrapetitel" placeholder="https://www.thebabyscorner.be/nl-be/baby_eten_en_drinken/">
</div>
<div >
<label for="text" >
Filter:
</label>
<input type="text" required name="filter" id="url" placeholder=".1-products-item">
</div>
<div >
<label for="webpicker" >Winkel:</label>
<select name="website_id" id="" >
<option value="#" disabled selected>Kies je winkel</option>
@foreach ($websites as $web)
<option value="{{ $web->id }}" >{{ $web->title }}</option>
@endforeach
</select>
</div>
<div >
<label for="webpicker" >Categorie:</label>
<select name="category_id" id="" >
<option value="#" disabled selected>Kies je categorie</option>
@foreach ($categories as $cat)
<option value="{{ $cat->id }}" >{{ $cat->title }}</option>
@endforeach
</select>
<button type="submit" name="scrape_submit">toevoegen</button>
</div>
</form>
<div >
<div >
<form action="{{ route('delLink', Auth()->user()) }}" method="POST">
@csrf
@method('DELETE')
<table >
<tr >
<td ><strong>Url</strong></td>
<td ><strong>Filter selector</strong></td>
<td ><strong>Website</strong></td>
<td ><strong>Categorie</strong></td>
<td></td>
<td></td>
</tr>
@foreach ($links as $link)
<tr data-id="{{ $link->id }}" >
<td >{{ $link->url }}</td>
<td >{{ $link->main_filter_selector }}</td>
<td >{{ $link->website->title }}</td>
<td >{{ $link->category->title }}</td>
<td ><button type="submit">Scrape</button></td>
<td ><button type="submit">Verwijderen</button>
</td>
</tr>
@endforeach
</table>
</form>
</div>
</div>
</div>
</div>
</div>
</main>
@include('partials.footer')
</body>
My routes:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\DashController;
use App\Http\Controllers\ListviewController;
use App\Http\Controllers\NewlistController;
use App\Http\Controllers\BabyController;
use App\Http\Controllers\ScrapeController;
use App\Http\Controllers\AdminController;
use App\Http\Controllers\ItemsController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
require __DIR__.'/auth.php';
Route::get('/', [HomeController::class, 'home'])->name('home');
Route::get('/home', [HomeController::class, 'home']);
Route::get('/listview', [ListviewController::class, 'listview'])
->name('lists');
Route::middleware('auth')->group (function ()
{
Route::get('/create', [NewlistController::class, 'newlist'])
->name('create');
Route::get('/dashboard/{role}/{id?}', [DashController::class, 'dashboard'])
->name('dashboard');
Route::post('/dashboard/{role}/{id}', [NewlistController::class, 'store']);
Route::get('/dashboard/{user_id}/{baby}', [BabyController::class, 'show'])
->name('baby');
Route::get('/dashboard/{user_id?}/{baby}/catalogus', [ScrapeController::class, 'show']);
Route::get('/admin/{id}', [AdminController::class, 'showAdmin'])
->name('admin');
Route::post('/admin/{id}/websites/', [AdminController::class, 'storeWeb'])
->name('newWeb');
Route::delete('/admin/{id}/websites/', [AdminController::class, 'destroyWeb'])
->name('delWeb');
Route::post('/admin/{id}/categories/', [AdminController::class, 'storeCat'])
->name('newCat');
Route::delete('/admin/{id}/categories/', [AdminController::class, 'destroyCat'])
->name('delCat');
Route::post('/admin/{id}/links/', [AdminController::class, 'storeLink'])
->name('newLink');
Route::delete('/admin/{id}/links/', [AdminController::class, 'destroyLink'])
->name('delLink');
});
CodePudding user response:
Replace this code
<form action="{{ route('delLink', Auth()->user()) }}" method="POST">
@csrf
@method('DELETE')
<table >
<tr >
<td ><strong>Url</strong></td>
<td ><strong>Filter selector</strong></td>
<td ><strong>Website</strong></td>
<td ><strong>Categorie</strong></td>
<td></td>
<td></td>
</tr>
@foreach ($links as $link)
<tr data-id="{{ $link->id }}" >
<td >{{ $link->url }}</td>
<td >{{ $link->main_filter_selector }}</td>
<td >{{ $link->website->title }}</td>
<td >{{ $link->category->title }}</td>
<td ><button type="submit">Scrape</button></td>
<td ><button type="submit">Verwijderen</button>
</td>
</tr>
@endforeach
</table>
</form>
With this
<table >
<tr >
<td ><strong>Url</strong></td>
<td ><strong>Filter selector</strong></td>
<td ><strong>Website</strong></td>
<td ><strong>Categorie</strong></td>
<td></td>
<td></td>
</tr>
@foreach ($links as $link)
<tr data-id="{{ $link->id }}" >
<td >{{ $link->url }}</td>
<td >{{ $link->main_filter_selector }}</td>
<td >{{ $link->website->title }}</td>
<td >{{ $link->category->title }}</td>
<td ><button type="submit">Scrape</button></td>
<td >
<form action="{{ route('delLink', $link->id) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit">Verwijderen</button>
</form>
</td>
</tr>
@endforeach
</table>
Your destroyLink()
method should contain this
public function destroyLink(Request $request)
{
$id = $request->id;
$link = Link::find($id);
$link->delete();
return back();
}