Someone2088's avatar

Get a 404 error when making a request via new route

I am trying to add some new functionality to a Laravel application I've just started working on- I have never used Laravel before, and only used PHP very briefly while at university about 9/10 years ago.

I've added a couple of input fields to a form in a dialog that's displayed on one of the pages- when a value is entered/ changed in either of these fields, a request should be made to update the value of a field in one of the database tables.

I've set the (change) attribute of the fields to call the Angular function- updatePreferredAddresseeDetails($event, payer), and within that function, have added a call to the PHP function that should perform the request- this.provService.updatePreferredAddresseeDetails(payer).subscribe();.

Currently, when I make a change to one of these fields on the form, and tab out of them, I can see in the console debug that the Angular function is called, but then get an error that says:

POST http://... 404 Not Found

In the routes/web.php file, I added a new route for the request I want to make with:

Route::group(['prefix' => 'prov'], function() {
    ...
    Route::post('preferredAddressee', 'WebApi\ProvController@updatePreferredAddresseeDetails');
});

The PHP function is defined with:

public function updatePreferredAddresseeDetails(Request $request)
{
    try
    {
        DB::beginTransaction();

        $transactionContactId = $request->input('transactionContactId');
        $transactionItemId = $request->input('transactionItemId');
        //dd("transactionItemId: ", $transactionItemId);

        if ($transactionItem = transactionItem::find($transactionItemId))
        {
            $transaction = $transactionItem->transaction;

            if (User::canAccessTransaction( auth()->user()->user, $transaction))
            {
                $transaction->savePropertyValueByPropertyTag('TRANSACTIONCONTACT', $transactionContactId);
                $account = Account::find($transaction->accountId);
                $account->savePropertyValueByPropertyTag('ADDRESSEENAME', $request->input('contactPreferredName'));
                $account->savePropertyValueByPropertyTag('ADDRESSEENAMEPDF', $request->input('contactPreferredAddresseeName'));

                $trasaction->save();
                $account->save();

                /*$newContact = User::find($transactionContactId); /*ERF(23/10/2018 @ 1450) shouldn't need this line, as it's not a new contact- just updating an
                                                                    existing one*/
                DB::commit();

                return response()->json([
                    'success' => true,
                    'transactionItemId' => $transactionItem->transactionItemId,
                    'transactionId' => $transactionItem->transactionId,
                    'transactionContactId' => $transactionContactId, //ERF(18/10/2018 @ 1220) transactionContactId is not a property of transactionItem
                    'addresseeName' => $account->ADDRESSEENAME,
                    'addresseeNamePdf' => $account->ADDRESSEENAMEPDF,
                    //'transactionContactName' => $newContact,
                    //dd(response);
                ]);
            }

            dd("transactionItem: ", $transactionItem);
        }
        else
        {
            dd("transactionItem could not be found ");
        }
    }
    catch(Excetpion $e)
    {
        dd("exception caught: ", $e);
    }
}

Where I'm calling this function from the Angular, I have the code:

    this.provService.updatePreferredAddresseeDetails(payer).subscribe(
        (response:any) => {
            payer.addresseename = response.addresseename;
            payer.addresseenamepdf = response.addresseenamepdf;

            const message = new Message();
            message.type = MessageType.SUCCESS;
            message.message = 'Preferred Addressee details have been updated. ';
            this.messagingService.emitMessage(message);

            payer.loading = false;
        },
        (error:any) => {
            //reset the names back to what they were originally because saving failed
            payer.addresseename = payer.originalAddresseeName;
            const message = new Message();
            message.type = MessageType.ERROR;
            message.message = error.message || 'There was a problem updaing the preferred addressee details. If the problem persists, please contact us.';
            this.messagingService.emitMessage(message);

            payer.loading = false;
        }
    );

When it's called, the message There was a problem updating the preferred addressee details. If the problem persists, please contact us. is displayed int he browser, so this tells me that there's an error in the response returned by the PHP function, but I can't seem to work out what I'm doing wrong there...

In the browser console, under Network-> Preview, I get a page that says You've tried to access a page that doesn't exist.

Anyone have any suggestions?

0 likes
8 replies
MikeMacDowell's avatar

@Someone2088 it's purely speculation based on your error and my experiences, but usually you get a 404 in this situation where your new route URI satisfies a previous route in the routes file.

Example:

Route::get('posts/{id}', 'PostsController@show');
Route::get('posts/no-replies', 'PostsController@noReplies');

If you have these two routes in your routes file, when hitting the URI /posts/no-replies it takes the "no-replies" as the wildcard {id} from the first route, and hits the store method first, because this pattern matches this route. This would lead to a 404 because no resources with id = 'no-replies' exists.

This is because the routes file is parsed top to bottom to match the current URI.

To avoid this problem, place specific routes before wildcard routes that they would match against

Route::get('posts/no-replies', 'PostsController@noReplies');
Route::get('posts/{id}', 'PostsController@show');

This arrangement will solve this problem.

Hopefully that's your issue.

Someone2088's avatar

@MikeMacDowell Thanks for your reply.

I can't spot any other routes that this new route URI would satisfy within this section, but just to be sure, I moved it to the top of the function. However I still get the same issue when it's called...

In my routes/web.php file, I now have:

Route::group(['prefix' => 'prov'], function() {
    Route::post('preferredAddressee', 'WebApi\T\ProvController@updatePreferredAddresseeDetails');
            Route::post('search', 'WebApi\T\ProvController@search');

This group has a lot of other routes assigned to it, but I can't see any that look like they conflict... at least, not as far as I can tell... What should I be looking for to check that they don't conflict?

MikeMacDowell's avatar

@Someone2088 what's the exact 404 message being returned? Can you see a stack trace as part of it? That should give you a hint as to which Controller and method are being called.

Someone2088's avatar

@MikeMacDowell The exact 404 message being returned is:

POST http://mysite.test/web-api/prov/preferredAddressee 404 (Not Found)

scheduleTask    @   polyfills.bundle.js?ver=421021188:8314
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask  @   polyfills.bundle.js?ver=421021188:5786
onScheduleTask  @   polyfills.bundle.js?ver=421021188:5676
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask  @   polyfills.bundle.js?ver=421021188:5780
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.scheduleTask  @   polyfills.bundle.js?ver=421021188:5611
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @   polyfills.bundle.js?ver=421021188:5634
scheduleMacroTaskWithCurrentZone    @   polyfills.bundle.js?ver=421021188:6471
(anonymous) @   polyfills.bundle.js?ver=421021188:8346
proto.(anonymous function)  @   polyfills.bundle.js?ver=421021188:6751
(anonymous) @   vendor.bundle.js?ver=605619721:82227
webpackJsonp../node_modules/rxjs/_esm5/Observable.js.Observable._trySubscribe   @   vendor.bundle.js?ver=605619721:102020
webpackJsonp../node_modules/rxjs/_esm5/Observable.js.Observable.subscribe   @   vendor.bundle.js?ver=605619721:102008
webpackJsonp../node_modules/rxjs/_esm5/operators/map.js.MapOperator.call    @   vendor.bundle.js?ver=605619721:120275
webpackJsonp../node_modules/rxjs/_esm5/Observable.js.Observable.subscribe   @   vendor.bundle.js?ver=605619721:102005
webpackJsonp../node_modules/rxjs/_esm5/operators/catchError.js.CatchOperator.call   @   vendor.bundle.js?ver=605619721:116809
webpackJsonp../node_modules/rxjs/_esm5/Observable.js.Observable.subscribe   @   vendor.bundle.js?ver=605619721:102005
webpackJsonp../src/app/pages/dashboard/manage/provisional-reminders/provisional-reminders.ts.ProvisionalRemindersComponent.updatePreferredAddresseeDetails  @   provisional-remi…module.chunk.js:948
(anonymous) @   ProvisionalRemind…sComponent.html:361
handleEvent @   vendor.bundle.js?ver=605619721:66540
callWithDebugContext    @   vendor.bundle.js?ver=605619721:68049
debugHandleEvent    @   vendor.bundle.js?ver=605619721:67636
dispatchEvent   @   vendor.bundle.js?ver=605619721:62955
(anonymous) @   vendor.bundle.js?ver=605619721:63580
(anonymous) @   vendor.bundle.js?ver=605619721:87702
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask    @   polyfills.bundle.js?ver=421021188:5800
onInvokeTask    @   vendor.bundle.js?ver=605619721:57733
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask    @   polyfills.bundle.js?ver=421021188:5799
webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.runTask   @   polyfills.bundle.js?ver=421021188:5567
webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask    @   polyfills.bundle.js?ver=421021188:5875
invokeTask  @   polyfills.bundle.js?ver=421021188:6896
globalZoneAwareCallback

I don't know if this makes things any clearer?

MikeMacDowell's avatar

@Someone2088 okay, that's the javascript errors caused by the 404 I'm assuming.

You can run "php artisan route:list" from the console to view a list of routes for the project. This should give you some idea as to possible conflicts.

You can use the --name= option to filter down the list of routes too.

It's also possible to look in storage/logs/laravel.log and see the 404 error, this should have a PHP stack trace for the error too.

Someone2088's avatar

@MikeMacDowell I tried running php artisan route:list, but that gave the error: Uncaught SyntaxError: Unexpected identifier, do I need to do something to pass the list identifier?

Toward the end of the laravel.log file, there's the line:

[2018-10-24 11:14:57] local.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Parse error: syntax error, unexpected ';', expecting ']' in /home/vagrant/code/app/Http/Controllers/WebApi/T/ProvController.php:2501

Line 2501 is the commented //dd("response: ", response); line at the end of the PHP function:

return response()->json([
                    'success' => true,
                    //'transactionItemId' => $transactionItem->transactionItemId,
                    //'transactionId' => $transactionItem->transactionId,
                    //'transactionContactId' => $transactionContactId, //transactionContactId is not a property of transactionItem
                    'addresseeName' => $account->ADDRESSEENAME,
                    'addresseeNamePdf' => $account->ADDRESSEENAMEPDF,
                    //'transactionContactName' => $newContact,
                    //dd("response: ", response);
                ]);

I'm fairly sure I should have the ; it seems to be complaining about at the end of the return statement... Is there something else I'm doing wrong here?

MikeMacDowell's avatar
Level 25

@Someone2088 I'm not sure what else to suggest, you'll just have to take a logical approach to debugging - maybe clear out everything in the Controller method and then add it all back in slowly.

Keep checking the log file as this will show any errors that are being thrown.

Hope you find the problem!

Someone2088's avatar

@MikeMacDowell Thanks for your help- turns out the string I had assigned to the URL in the service.ts file was missing a couple of route prefixes. Once I added the missing prefixes, the function was called correctly.

private preferredAddresseeDetailsUpdateUrl: string = BASE_URL + '/web-api/t/prov/preferredAddressee';
1 like

Please or to participate in this conversation.