jadjoubran / laravel5-angular-material-starter

Get started with Laravel 5.3 and AngularJS (material)
https://laravel-angular.readme.io/
MIT License
1.66k stars 400 forks source link

Implementing API auth with ng-file-upload #294

Closed Neo-89 closed 8 years ago

Neo-89 commented 8 years ago

Hi guys,

I am aware that my problem might be trivial but i'm trying to implement ng-file-upload - https://github.com/danialfarid/ng-file-upload with auth API in your laravel angular starter. Default code for ng-file-upload is

   upload(dataUrl, name) {
        this.Upload.upload({
            url: '/addons',
            data: {
                file: this.Upload.dataUrltoBlob(dataUrl, name),
                name: this.name
            }
        }).then((response) => { ...

this works in routes:

Route::group(['middleware' => ['web']], function () {
    Route::post('/addons', 'AddonsController@create');
});

but i don't know how should I implement with api.auth

Component:

         var data = {
             file: this.Upload.dataUrltoBlob(dataUrl, name)  // doesn't work
         };
         this.API.all('addons').post(data)
             .then((response) => {
                // response
             });

Routes

$api->group(['middleware' => ['api', 'api.auth']], function ($api) {
    $api->post('addons', 'AddonsController@create');
});

I do not expect a ready solution. Thanks for any hint. You are doing a great job. Thanks!

flick36 commented 8 years ago

I haven't use the library, but i'm planning on to in a nearby future, so i sure wan't to know how to solve this, so let's try to make it work, i have quickly read the Wiki and apparently you should use it like:

Upload.upload({
    url: 'api/adaddons', 
    method: 'POST',
    sendFieldsAs: 'form',
    data: {
        file: this.Upload.dataUrltoBlob(dataUrl, name),
        name: this.name
    }
})

something like that? .-.

shiruken1 commented 8 years ago

Hey guys! It's super easy. Just add:

                headers: { 'Authorization': 'Bearer ' + $auth.getToken() },
                withCredentials: true,

Cheers!

albertojm commented 8 years ago

Hey guys!

I'm trying to implement this same package, what i've donde so far is:

Added in index.modules.js

angular.module('app.components', [ 'ui.router', 'ngMaterial', 'angular-loading-bar', 'restangular', 'ngStorage', 'satellizer', 'ngFileUpload' ]);

Created a new component called file-upload (php artisan ng:component file-upload) that looks like this:

class FileUploadController{ constructor(API, ngFileUpload, $state){ 'ngInject'; } $onInit(){ } }

And my file-upload-component.html looks like this:

`

Select
    </md-input-container>
</div>
<div>
    <md-input-container class="FileUpload-inputContainer">
        <label>Email</label>
        <input type="email" ng-model="vm.email">
    </md-input-container>
</div>
<div>
    <md-input-container class="FileUpload-inputContainer">
        <label>Mensaje</label>
        <textarea ng-model="vm.message" placeholder="Mensaje..."></textarea>
    </md-input-container>
</div>

`

But I'm getting this error:

Error: [$injector:unpr] Unknown provider: ngFileUploadProvider <- ngFileUpload

What I'm missing? I would appreciate any hints on this.

Thanks!

flick36 commented 8 years ago

@albertojm in you FileUploadController you should inject Upload not ngFileUpload

Also can you please use 3 backticks ``` instead of one to properly format your code

albertojm commented 8 years ago

Thanks @flick36, that solved it!

But now i'm getting:

Error: dataurl is undefined

class FileUploadController{
    constructor(API, ToastService, $state, $auth, Upload){
        'ngInject';

        this.API = API;
        this.$state = $state;
        this.ToastService = ToastService;
        this.Upload = Upload;
    }

    $onInit(){
        this.file = '';
    }

    submit(dataUrl, name) {

        this.Upload.upload({
            url: '/api/v1/file',
            method: 'POST',
            sendFieldsAs: 'form',
            data: {
                file: this.Upload.dataUrltoBlob(dataUrl, name),
                email: this.email,
                message: this.message
            },
            headers: { 'Authorization': 'Bearer ' + $auth.getToken() },
            withCredentials: true
        }).then(() => {
            this.ToastService.show(`Archivo subido correctamente`);
            this.$state.go('app.dashboard');
        });
    }

} 
flick36 commented 8 years ago

@albertojm i think you have no idea how to program in JS or AngularJS... i can't help you until you properly format your code bro, that submit function never seems to be called because for what i can see you submit your form with vm.upload() wich i don't see in your controller.

albertojm commented 8 years ago

Haha, don't worry mate. I've already got it working:

class FileUploadController{
    constructor(API, ToastService, $state, $auth, Upload){
        'ngInject';

        this.API = API;
        this.$state = $state;
        this.ToastService = ToastService;
        this.Upload = Upload;
        this.$auth = $auth;
    }

    submit(){
        console.log(this.file);
        this.Upload.upload({
            url: '/api/v1/file',
            method: 'POST',
            sendFieldsAs: 'form',
            data: {
                file: this.file,
                email: this.email,
                message: this.message
            },
            headers: { 'Authorization': 'Bearer ' + this.$auth.getToken() },
            withCredentials: true
        }).then(() => {
            this.ToastService.show('Archivo subido correctamente');
            this.$state.go('app.dashboard');
        });
    }

}

Thanks for all :)

flick36 commented 8 years ago

@albertojm cool can you post your controller on the server side? to improve the help in the post? for people like @Neo-89 that want to know how to implement it?

albertojm commented 8 years ago

Of course, I'm uploading files to s3.

Btw, I was using vm.submit() to submit the form, but still dataUrl was undefined.

public function store(Request $request, MimeType $mimetype)
    {

            $this->validate($request, [
                'file'      => 'required',                                            
            ]);

            $s3 = \Storage::disk('s3');

            $user_id = Auth::id();
            $uploaded_file = $request->file('file');           

            // Optional fields

            $expiry = date("Y-m-d", strtotime( $request->input('expiry') ));            
            $notification_email = $request->input('notification_email');

            $extension = $uploaded_file->getClientOriginalExtension();
            $size = $uploaded_file->getSize();      
            $uploadFileName = time().'.'.$extension;              
            $url = 'http://s3.amazonaws.com/file-uploads/'.$uploadFileName;
            $mime = $mimetype->detectByFileExtension($extension);

            if(!empty( $request->input('url') )) :
                $tinyurl = $request->input('url');
            else:
                $tinyurl = substr(md5(uniqid(mt_rand(), true)), 0, 8);
            endif;          

            $upload = Storage::disk('s3')->getDriver()->getAdapter()->getClient()->putObject(array(
                'Bucket'        => env('S3_BUCKET'),
                'Key'           => $uploadFileName,
                'Body'          => file_get_contents($uploaded_file),
                'ACL'           => 'public-read',
                'ContentType'   => $mime,
                //'Expires'       => $expiry, 
                'CacheControl'  => 'max-age'
            ));

            if($upload) :

                $file           = new File;
                $file->path     = $tinyurl;
                $file->mimetype = $mime;
                $file->size     = $size;
                $file->type     = 'share';
                $file->url      = $url;
                $file->expiry   = $expiry;
                $file->user_id  = $user_id;

                $file->save();

                return response()->success(compact('file'));

            else:
                return response()->error('Could not create file.');
            endif;
    }
flick36 commented 8 years ago

@Neo-89 was your problem solved?

dpmontero commented 8 years ago

Hi guys!! Sorry, I have a problem:

Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:modulerr] Failed to instantiate module app.components due to:
Error: [$injector:modulerr] Failed to instantiate module ngFileUpload due to:
Error: [$injector:nomod] Module 'ngFileUpload' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.5.7/$injector/nomod?p0=ngFileUpload
    at http://localhost:8000/build/js/vendor-1e8312894e.js:68:12
    at http://localhost:8000/build/js/vendor-1e8312894e.js:2075:17
    at ensure (http://localhost:8000/build/js/vendor-1e8312894e.js:1999:38)
    at module (http://localhost:8000/build/js/vendor-1e8312894e.js:2073:14)
    at http://localhost:8000/build/js/vendor-1e8312894e.js:4608:22
    at forEach (http://localhost:8000/build/js/vendor-1e8312894e.js:321:20)
    at loadModules (http://localhost:8000/build/js/vendor-1e8312894e.js:4592:5)
    at http://localhost:8000/build/js/vendor-1e8312894e.js:4609:40
    at forEach (http://localhost:8000/build/js/vendor-1e8312894e.js:321:20)
    at loadModules  @(http://localhost:8000/build/js/vendor-1e8312894e.js:4592:5)

index.module.js

angular.module('app', [
  'app.run',
    'app.filters',
    'app.services',
    'app.components',
  'app.directives',
    'app.routes',
    'app.config',
    'app.partials'
]);

angular.module('app.run', []);
angular.module('app.routes', []);
angular.module('app.filters', []);
angular.module('app.services', []);
angular.module('app.config', []);
angular.module('app.directives', []);
angular.module('app.components', [
    'ui.router', 'ngMaterial', 'angular-loading-bar',
    'restangular', 'ngStorage', 'satellizer', 'ngFileUpload'
]);

The controller like @albertojm.

The version of laravel-angular-material-starter is actual: --prefer-dist

I installed npm install ng-file-upload. At the directory: "laravel5-angular-material-starter/node_modules/ng-file-upload"

I would appreciate any hints on this. Thanks!

jadjoubran commented 8 years ago

Hi @dpmontero Unfortunately only bower is supported for now for front-end packages, so you need to bower install it with a --save argument just like in the docs