未捕获(承诺中)类型错误:无法读取未定义的属性“uid”

Posted

技术标签:

【中文标题】未捕获(承诺中)类型错误:无法读取未定义的属性“uid”【英文标题】:Uncaught (in promise) TypeError: Cannot read property 'uid' of undefined 【发布时间】:2017-08-12 13:50:56 【问题描述】:

我正在使用 laravel 5.4 和 Vue.js 2 将一些信息与文件(视频)一起保存在 DB 中。但是我遇到了这样的错误

错误:http://imgur.com/a/7XGERPUT

http://localhost:8000/videos/null 404 (Not Found)

Uncaught (in promise) TypeError: Cannot read property 'uid' of undefined

NotFoundHttpException in Handler.php line 131:
No query results for model [App\Models\Video].

路线:

Route::group(['middleware'=>['auth']],function()

    Route::get('/upload','VideoUploadController@index');
    Route::post('/videos','VideoController@store');
    Route::put('/videos/video','VideoController@update');


    Route::get('/channel/channel/edit','ChannelSettingsController@edit');
    Route::put('/channel/channel/edit','ChannelSettingsController@update');

);

控制器:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\VideoUpdateRequest;
use App\Models\Video;
class VideoController extends Controller

    public function store(Request $request)
    
        $uid = uniqid(true);

        $channel = $request->user()->channel()->first(); 

        $video = $channel->video()->create([

            'uid'=>$uid,
            'title'=>$request->title,
            'description'=>$request->description,
            'visibility'=>$request->visibility,
            'video_filename'=>"$uid.$request->extension",
            ]);
        return response()->json([
            'data' => [
                'uid' => $uid
            ]
        ]);
    

    public function update(VideoUpdateRequest $request, Video $video)
    

     //authentication checked here .......


        $video->update([
            'title' => $request->title,
            'description' => $request->description,
            'visibility' => $request->visibility,
            'allow_votes' => $request->has('allow_votes'),
            'allow_comments' => $request->has('allow_comments')
        ]);

        if ($request->ajax()) 
            return response()->json(null, 200);
        

        return redirect()->back();
    

上传.vue

 <template>
        <div class="container">
            <div class="row">
                <div class="col-md-8 col-md-offset-2">
                    <div class="panel panel-default">
                        <div class="panel-heading">Example Component</div>

                        <div class="panel-body">
                           <input type="file" name="video" id="video" @change="changfileInputChange" v-if="!uploading">
                           <div id="video-form" v-if="uploading&&!failed">

                           <div class="form-group">
                                <label for="title">Title</label>
                                <input type="" name="" v-model="title" class="form-control">

                           </div>

                            <div class="form-group">
                                <label for="description">Description</label>
                                <textarea class="form-control"v-model="description"></textarea>

                           </div>

                            <div class="form-group">
                                <label for="visibility">Visibility</label>
                                <select class="form-control" v-model="visibility">
                                    <option value="private">Private</option>
                                    <option value="public">Public</option>
                                    <option value="unlisted">Unlisted</option>
                                </select>

                           </div>
                               <span class="help-block pull-right">saveStatus</span>
                             <button class="btn btn-default" type="submit"@click.prevent="update">Save changes</button>
                           </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </template>

<script>
    export default 
        mounted() 
            console.log('Component mounted.')
        ,

        data()
        
            return
                uid:null,
                uploading:false,
                uplodComplete:false,
                failed:false,
                title:'unlisted',
                description:null,
                visibility:'private',
                saveStatus:null
            

        ,

        methods:
            changfileInputChange()
            
                this.uploading=true;
                this.failed=false;
                this.file=document.getElementById('video').files[0];

                this.storeVideo().then(()=>

                )
            ,

            storeVideo()
                return this.$http.post('/videos',
                    title:this.title,
                    description:this.description,
                    visibility:this.visibility,
                    extension:this.file.name.split('.').pop()

                ).then((response)=>
                    this.uid = response.json().data.uid;
                );
            ,
            update() 
                this.saveStatus = 'Saving changes.';

                return this.$http.put('/videos/' + this.uid, 
                    title: this.title,
                    description: this.description,
                    visibility: this.visibility
                ).then((response) => 
                    this.saveStatus = 'Changes saved.';

                    setTimeout(() => 
                        this.saveStatus = null
                    , 3000)
                , () => 
                    this.saveStatus = 'Failed to save changes.';
                );
            
        
    
</script>

首先,我将视频连同标题、描述等的默认值与 ajax 请求一起保存到数据库,请参阅 Video.vue 代码

我在控制台中通过 store 方法获得 uid(unique id for video),但是当我通过单击保存 chages 按钮进行更新时,出现如下错误:

当我在控制器中使用默认 uid

public function store(Request $request)
    
        $uid = '158cfff622e1b7';

       //....some code here
    //finally return $uid
return response()->json([
            'data' => [
                'uid' => $uid
            ]
        ]);

如果我将uid 更改为默认158cfff622e1b7,则在Upload.vue 这一行中,它可以正常工作,即:结果已更新

return this.$http.put('/videos/' +'158cfff622e1b7', 
//code

);
    it means i am not getting `uid` ,or something is wrong,please help me      

这里是错误截图:http://imgur.com/a/7XGER

错误:PUT http://localhost:8000/videos/null 404 (Not Found)

【问题讨论】:

【参考方案1】:

我可以看到您正在使用路由模型绑定。

Route::put('/videos/video','VideoController@update');

路由模型绑定使用 ID 字段开箱即用。如果您使用不同的密钥,则需要告诉您的模型使用该密钥进行路由模型绑定。

在视频模型中添加

public function getRouteKeyName() 
    return 'uid';

更新

在providers/RouteServiceProvider中,在boot()里面添加这个

Route::bind('video', function ($value) 
    return App\Models\Video::where('uid', $value)->first();
);

如果还是不行,就拿视频更新一下吧,老办法

public function update(VideoUpdateRequest $request, $uid)

    $video = Video::where('uid', $uid)->first();
    $video->title = $request->title;
    $video->description = $request->description;
    ...
    $video->update();

    if ($request->ajax()) 
        return response()->json(null, 200);
    

    return redirect()->back();

【讨论】:

我在视频模型中写过 公共函数 channel() return $this->belongsTo(Channel::class); 公共函数 getRouteKeyName() return 'uid'; 检查我的更新。为确保您的路线模型绑定有效,请尝试简单地获取视频。没有其他的。刚收到视频 我得到这个:没有模型 [App\Models\Video] 的查询结果。 您可以尝试像我刚才那样使用旧方法。如果你真的想让它炒起来。但是如果你必须通过路由模型绑定来做到这一点,那么一切都很好。【参考方案2】:

this.uid = response.body.data.uid;替换这个this.uid = response.json().data.uid;

它必须工作,如果不让我听到的话

阅读Docs了解更多

【讨论】:

谢谢@Ranjit Karki,现在可以使用了。非常感谢

以上是关于未捕获(承诺中)类型错误:无法读取未定义的属性“uid”的主要内容,如果未能解决你的问题,请参考以下文章

未捕获(承诺中)类型错误:无法读取未定义的属性“协议”

未捕获(承诺中)类型错误:无法读取未定义的属性“uid”

如何修复此错误:未捕获(承诺)类型错误:无法读取未定义的属性(读取“长度”)

在与 API 调用关联的函数中:未捕获(承诺中)类型错误:无法读取未定义的属性“包含”

VueJS 3 / 路由器 / 带有推送的重定向:未捕获(承诺中)类型错误:无法读取未定义的属性(读取“推送”)

VueJS:未捕获(承诺中)TypeError:无法读取未定义的属性“推送”