Отправка изображения из ionic 4 с помощью почтового запроса - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь отправить изображение, захваченное плагином Cordova - camera, с помощью пост-запроса.

Отправка на Django rest-framework.это выдает мне ошибку type is not file

код, который я использую в моем файле .ts:

import {Component, OnInit} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {HttpClient} from '@angular/common/http';
import {HttpHeaders} from '@angular/common/http';
import {Router} from '@angular/router';
import {ActionSheetController} from '@ionic/angular';
import {Camera, CameraOptions} from '@ionic-native/camera/ngx';

@Component({
    selector: 'app-add-dress',
    templateUrl: './add-dress.page.html',
    styleUrls: ['./add-dress.page.scss'],
})
export class AddDressPage implements OnInit {
    cats: Observable<any>;
    types: Observable<any>;
    sizes: Observable<any>;
    actions: Observable<any>;
    cities: Observable<any>;
    pic: any;
    img_1: any;
    img_2: any;
    img_3: any;
    title = '';
    desc = '';
    color = '';
    category = '';
    type = '';
    size = '';
    action = '';
    price = '';
    city = '';
    number = '';
    CategoryActionSheetOptions: any = {
        header: 'Category',
        subHeader: 'Select your dress Category'
    };
    TypeActionSheetOptions: any = {
        header: 'Type',
        subHeader: 'Select your dress Type'
    };
    SizeActionSheetOptions: any = {
        header: 'Size',
        subHeader: 'Select your dress Size'
    };
    ActionActionSheetOptions: any = {
        header: 'Dress Action',
        subHeader: 'Dress is for Sale or Rental'
    };
    CityActionSheetOptions: any = {
        header: 'City',
        subHeader: 'Select your City'
    };

    constructor(public httpClient: HttpClient, private router: Router, public actionSheetController: ActionSheetController,
                private camera: Camera) {
        const httpOptions = {
            headers: new HttpHeaders({
                'Content-Type': 'application/json',
                'Authorization': 'Basic ' + btoa('username:password')
            })
        };

        this.cats = this.httpClient.get('https://www.fostania.com/api/categories/', httpOptions);
        this.cats.subscribe(data => {
            this.cats = data;
            console.log('my data: ', data);
        });
        this.types = this.httpClient.get('https://www.fostania.com/api/types/', httpOptions);
        this.types.subscribe(data => {
            this.types = data;
            console.log('my data: ', data);
        });
        this.sizes = this.httpClient.get('https://www.fostania.com/api/sizes/', httpOptions);
        this.sizes.subscribe(data => {
            this.sizes = data;
            console.log('my data: ', data);
        });
        this.actions = this.httpClient.get('https://www.fostania.com/api/actions/', httpOptions);
        this.actions.subscribe(data => {
            this.actions = data;
            console.log('my data: ', data);
        });
        this.cities = this.httpClient.get('https://www.fostania.com/api/cities/', httpOptions);
        this.cities.subscribe(data => {
            this.cities = data;
            console.log('my data: ', data);
        });
    }

    // take Photo
    takePhoto(sourceType: number, img_num) {
        const options: CameraOptions = {
            quality: 50,
            destinationType: this.camera.DestinationType.DATA_URL,
            encodingType: this.camera.EncodingType.JPEG,
            mediaType: this.camera.MediaType.PICTURE,
            correctOrientation: true,
            sourceType: sourceType,
        };

        this.camera.getPicture(options).then((imageData) => {
            const base64Image = 'data:image/jpeg;base64,' + imageData;
            this.pic = base64Image;
            if (img_num === 'Image_1') {
                const thumb_1 = document.getElementById('thumb_1');
                const change_button_1 = document.getElementById('change_button_1');
                const add_button_1 = document.getElementById('add_button_1');
                thumb_1.hidden = false;
                change_button_1.hidden = false;
                add_button_1.hidden = true;
                this.img_1 = this.pic;
            }
            if (img_num === 'Image_2') {
                const thumb_1 = document.getElementById('thumb_2');
                const change_button_2 = document.getElementById('change_button_2');
                const add_button_2 = document.getElementById('add_button_2');
                thumb_1.hidden = false;
                change_button_2.hidden = false;
                add_button_2.hidden = true;
                this.img_2 = this.pic;
            }
            if (img_num === 'Image_3') {
                const thumb_1 = document.getElementById('thumb_3');
                const change_button_3 = document.getElementById('change_button_3');
                const add_button_3 = document.getElementById('add_button_3');
                thumb_1.hidden = false;
                change_button_3.hidden = false;
                add_button_3.hidden = true;
                this.img_3 = this.pic;
            }
        }, (err) => {
            console.log(err);
        });
    }

    async presentActionSheet(num) {
        const actionSheet = await this.actionSheetController.create({
            header: 'Add ' + ' ' + num,
            mode: 'ios',
            buttons: [{
                text: 'Take Photo',
                icon: 'camera',
                handler: () => {
                    console.log('take photo clicked');
                    this.takePhoto(1, num);
                }
            }, {
                text: 'Open Gallery',
                icon: 'list',
                handler: () => {
                    console.log('open gallery clicked');
                    this.takePhoto(0, num);
                }
            }, {
                text: 'Cancel',
                icon: 'close',
                role: 'cancel',
                handler: () => {
                    console.log('Cancel clicked');
                }
            }]
        });
        await actionSheet.present();
    }

    get_form_data() {
        console.log(this.title);
        console.log(this.desc);
        console.log(this.color);
        console.log(this.category);
        console.log(this.type);
        console.log(this.size);
        console.log(this.action);
        console.log(this.price);
        console.log(this.city);
        console.log(this.number);
        console.log(this.img_1);
        console.log(this.img_2);
        console.log(this.img_3);

        const httpOptions = {
            headers: new HttpHeaders({
                'Content-Type':  'application/json',
                'Authorization': 'Basic ' + btoa('username:password')
            })
        };
        const request =  {
            'item_title': this.title,
            'item_description': this.desc,
            'item_price' : this.price,
            'item_price_later': false,
            'item_action': this.action,
            'item_color': this.color,
            'item_category': this.category,
            'item_type': this.type,
            'item_size': this.size,
            'item_city': this.city,
            'item_phone': this.number,
            'item_image_1': this.img_1,
            'item_image_2': this.img_2,
            'item_image_3': this.img_3,
            'created_by': 7,
        };
        this.httpClient.post('https://www.fostania.com/api/items/', request, httpOptions)
            .subscribe(data => {
                console.log(data['_body']);
            }, error => {
                console.log(error);
            });

    }
    ngOnInit() {
    }

}

Как вы видите, некоторые запросы на получение данных с нужного мне сервераиспользовать в некоторых ion-select входах в файле .html.эта часть прекрасно работает

вот мой .html файл:

<ion-header>
    <ion-toolbar color="medium">
        <ion-buttons slot="start">
            <ion-menu-button></ion-menu-button>
        </ion-buttons>
        <ion-title>
            <ion-icon name="add"></ion-icon>
            Add your dress
        </ion-title>
    </ion-toolbar>
</ion-header>


<ion-content>
    <ion-card mode="ios">
        <ion-card-content>
            <h2>Add your Dress</h2>
            <small>fill the form to add your dress</small>
            <br><br>
            <h3>Dress Information:</h3>
            <ion-item>
                <ion-label position="floating" >Title</ion-label>
                <ion-input [(ngModel)]="title"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label position="floating" >Description</ion-label>
                <ion-textarea [(ngModel)]="desc"></ion-textarea>
            </ion-item>
            <ion-item>
                <ion-label position="floating">Color</ion-label>
                <ion-input [(ngModel)]="color"></ion-input>
            </ion-item>
            <br><br>
            <ion-item>
                <ion-label>Category</ion-label>
                <ion-select [interfaceOptions]="CategoryActionSheetOptions" interface="action-sheet"
                            placeholder="Select One" [(ngModel)]="category">
                    <ion-select-option *ngFor="let cat of cats" value="{{cat.id}}">{{cat.category_name}}</ion-select-option>
                </ion-select>
            </ion-item>
            <ion-item>
                <ion-label>Type</ion-label>
                <ion-select [interfaceOptions]="TypeActionSheetOptions" interface="action-sheet"
                            placeholder="Select One" [(ngModel)]="type">
                    <ion-select-option *ngFor="let type of types" value="{{type.id}}">{{type.type_name}}</ion-select-option>
                </ion-select>
            </ion-item>
            <ion-item>
                <ion-label>Size</ion-label>
                <ion-select [interfaceOptions]="SizeActionSheetOptions" interface="action-sheet"
                            placeholder="Select One" [(ngModel)]="size">
                    <ion-select-option *ngFor="let size of sizes" value="{{size.id}}">{{size.size_name}}</ion-select-option>
                </ion-select>
            </ion-item>
            <br><br>
            <h3>Price Information:</h3>
            <ion-item>
                <ion-label>Dress is for</ion-label>
                <ion-select [interfaceOptions]="ActionActionSheetOptions" interface="action-sheet"
                            placeholder="Select One" [(ngModel)]="action">
                    <ion-select-option *ngFor="let action of actions" value="{{action.id}}">{{action.action_name}}</ion-select-option>
                </ion-select>
            </ion-item>
            <ion-item>
                <ion-label position="floating">Price</ion-label>
                <ion-input type="number" [(ngModel)]="price"></ion-input>
            </ion-item>
            <br><br>
            <h3>Contact Information:</h3>
            <ion-item>
                <ion-label>City</ion-label>
                <ion-select [interfaceOptions]="CityActionSheetOptions" interface="action-sheet"
                            placeholder="Select One" [(ngModel)]="city">
                    <ion-select-option *ngFor="let city of cities" value="{{city.id}}">{{city.city_name}}</ion-select-option>
                </ion-select>
            </ion-item>
            <br>
            <ion-item>
                <ion-label position="floating">Phone Number</ion-label>
                <ion-input type="number" [(ngModel)]="number"></ion-input>
            </ion-item>
            <br><br>
            <h3>Dress Images:</h3>
            <ion-item>
                <ion-thumbnail id="thumb_1" hidden>
                    <img src="{{img_1}}">
                </ion-thumbnail>
                <br><br>
                <div id="add_button_1">
                    <ion-button color="success" (click)="presentActionSheet('Image_1')">
                        <ion-icon name="camera"></ion-icon>
                        Add Image 1
                    </ion-button>
                </div>
                <div id="change_button_1" hidden>
                    <ion-button color="primary" (click)="presentActionSheet('Image_1')">
                        <ion-icon name="camera" hidden></ion-icon>
                        change
                    </ion-button>
                </div>
            </ion-item>
            <ion-item>
                <ion-thumbnail id="thumb_2" hidden>
                    <img src="{{img_2}}">
                </ion-thumbnail>
                <br><br>
                <div id="add_button_2">
                    <ion-button color="success" (click)="presentActionSheet('Image_2')">
                        <ion-icon name="camera"></ion-icon>
                        Add Image 2
                    </ion-button>
                </div>
                <div id="change_button_2" hidden>
                    <ion-button color="primary" (click)="presentActionSheet('Image_2')">
                        <ion-icon name="camera" hidden></ion-icon>
                        Change
                    </ion-button>
                </div>
            </ion-item>
            <ion-item>
                <ion-thumbnail id="thumb_3" hidden>
                    <img src="{{img_3}}">
                </ion-thumbnail>
                <br><br>
                <div id="add_button_3">
                    <ion-button color="success" (click)="presentActionSheet('Image_3')">
                        <ion-icon name="camera"></ion-icon>
                        Add Image 3
                    </ion-button>
                </div>
                <div id="change_button_3" hidden>
                    <ion-button color="primary" (click)="presentActionSheet('Image_3')">
                        <ion-icon name="camera" hidden></ion-icon>
                        change
                    </ion-button>
                </div>
            </ion-item>
            <br><br>
            <ion-button expand="block" color="tertiary" (click)="get_form_data()"> Submit your dress</ion-button>
        </ion-card-content>
    </ion-card>
</ion-content>

HTML отлично работает, и когда я отправляю данные, я проверял свою вкладку network, и запрос находитсяпослал.

и вот ответ, который я получаю {"item_image_1":["The submitted data was not a file. Check the encoding type on the form."],"item_image_2":["The submitted data was not a file. Check the encoding type on the form."],"item_image_3":["The submitted data was not a file. Check the encoding type on the form."]}

1 Ответ

2 голосов
/ 28 марта 2019

У вас есть проблема здесь:

this.camera.getPicture(options).then((imageData) => {
            const base64Image = 'data:image/jpeg;base64,' + imageData;
        }, 
 this.img_2 = base64Image;

переменная this.img_2 установлена ​​ДО того, как камера сделала снимок, это означает, что this.img_2 будет нулевым .

Переместите его в свой обратный вызов:

this.camera.getPicture(options).then((imageData) => {
                const base64Image = 'data:image/jpeg;base64,' + imageData;
                this.img_2 = base64Image;
            }, 

, чтобы убедиться, что вы получаете изображение, прежде чем использовать его.

...