Unable to generate a preview of the image that has been uploaded [using the REST API

While attempting to upload from my Ionic App to the Codeigniter Rest Server, I encountered an issue where the image could not be previewed after it was opened. To guide me through the uploading process from the app's end, I followed this tutorial:

This is the code snippet from my Ionic App:

img = { "data":"", "user_id":"" };

getPhoto() {
  let options = {
    maximumImagesCount: 1
  };
  this.imagePicker.getPictures(options).then((results)=>{
    for(let i=0; i < results.length; i++){
      this.imgPreview = results[i];
      this.base64.encodeFile(results[i]).then((base64File: string) => {
        this.img.data = base64File;
        this.status = true;
      }, (err) => {
        console.log(err);
      });
    }
  });
}

// Function to submit the data to rest api
UploadImages(){
  this.restProvider.postAction('my-rest-api-url', this.img).then((data)=>{
      this.msg = JSON.stringify(data['img']);
      this.restProvider.triggerToastMsg('Images uploaded to gallery.');
  });
}

And this is the corresponding function on my Rest Server in Codeigniter:

function uploadImage_post(){
    $postdata = file_get_contents("php://input");
    $data = json_decode($postdata);

    if(!empty($data)){
        $img = $data->data;
        $imgStr = substr($img, strpos($img, "base64,") + 7);
        $imgData = base64_decode($imgStr);
        $imgName = uniqid().'.jpg';

        $imgData = array(
            'author_id'   => $data->user_id,
            'file_src'    => $imgName,
        );

        $this->Gallery_model->createMyGallery($imgData);
        $root = dirname($_SERVER['DOCUMENT_ROOT']);
        $dir = $root.'/my-dir-goes-here';
        file_put_contents($dir.$imgName, $imgData);

        $this->response([
            'http_status_code' => REST_Controller::HTTP_OK,
            'status' => true,
            'statusMsg' => 'OK'
        ], REST_Controller::HTTP_OK);
    }
}

Upon examining the API side, when accessing $data->data, it displays the encoded base64 data format which looks like

data:image/*;charset=utf-8;base64,/9j/4AAQSkZjRgA....................

To eliminate the prefix

data:image/*;charset=utf-8;base64,
, I utilized the substr() method to extract only the essential base64 data like
/9j/4AAQSkZjRgA....................
. Despite successfully storing the image in my server directory, attempts to open the image result in a corrupted file message. Additionally, the image size is significantly small at only 19 bytes.

Answer №1

Pay close attention to the server-side of your REST server. The issue lies in the fact that you are assigning a value to $imgData twice, which ends up replacing the decoded base64 value with an array value. As a result, when you try to save the image using

file_put_contents($dir.$imgName, $imgData);
, it fails to retrieve the correct image.

To resolve this issue, make sure to organize your code in the following order:


$img = $data->data;
$imgStr = substr($img, strpos($img, "base64,") + 7);
$imgData = base64_decode($imgStr);
$imgName = uniqid().'.jpg';

$root = dirname($_SERVER['DOCUMENT_ROOT']);
$dir = $root.'/my-dir-goes-here';
file_put_contents($dir.$imgName, $imgData);

$newImgData = array(
    'author_id'   => $data->user_id,
    'file_src'    => $imgName,
);

$this->Gallery_model->createMyGallery($newImgData);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

reading an array of objects using typescript

Trying to retrieve an object from an array called pVal. pVal is the array that includes objects. I am attempting to obtain the value of "group" based on the id provided. For instance, if the id is equal to 1, it should display "VKC". Any assistance woul ...

The submit button seems to be unresponsive or unreactive

As a newcomer to Angular 2 and Typescript, I am in the process of building a web application. I have created several input fields and, following user submission via a button, I want to log the inputs to the console. However, it seems like my button is not ...

A vertical divider within an ion-item collection

Currently, I am using Ionic and HTML to implement a vertical line within an ion-item in an ion-list. The desired outcome is to have something similar to this (the colored line after 'all-day'): I attempted the following approach: <ion-list&g ...

Exploring data binding in Angular 2 through ngModelChange

When it comes to data binding, achieving property and event binding is possible with $event representing the entered value below: <input [ngModel]="username" (ngModelChange)="change($event)"> But what does the following code snippet mean? <inpu ...

What is the purpose of having a constructor in Typescript when an interface is already used for a class?

Is it necessary to have a constructor in my class if the class already implements an interface? It seems like redundant code to me. interface PersonInterface { firstname: string; lastname: string; email: string; } class Person implements Pe ...

The dynamic duo of MongoDB and Prisma: forging a groundbreaking one-to-many relationship

Is it possible to establish a one-way m-to-n relationship without requiring both collections to have each other's ids? I am attempting the following: model Country { id String @id @default(auto()) @map("_id") @db.ObjectId ...

Ensure that the array is completely populated before calling it in Angular

My code starts with an empty array and I need to call a service that works with the populated array. Two service calls are used to populate the array, both fetching elements from an API. The issue is ensuring the last service call waits for the array to be ...

Why is it necessary to redefine the interface and its class in Typescript after initially defining the interface with implements?

interface Filter { rowAddRow: (treeData:Tree[],id:string,filterType:FilterType) =>Tree[] } class FilterAction implements Filter { // I must redeclare here to ensure the correct type for id rowAddRow(treeData:Tree[], id, filterType):Tree[] { ...

Accessing Nested FormGroup in Angular 6 by its name

Dealing with Nested Form Groups address = new FormGroup({ 'com.complex.Address':new FormGroup({ city: cityControl, streetName: streetNameControl, houseNumberAddition: houseNumberAdditionControl, ho ...

Class property in Typescript is initialized in the constructor, but is undefined in a member function

I'm encountering a recurring problem while developing an Electron application using Typescript. The backend has a set of controllers, with the AppController managing file system interactions and WindowController handling basic window functions. Here&a ...

Guide to organizing documents using an interface structure

I currently have an interface that outlines the structure of my documents within a specific collection: interface IGameDoc { playerTurn: string; gameState: { rowOne: [string, string, string] rowTwo: [string, string, string] ...

Which is the optimal choice: subscribing from within a subscription or incorporating rxjs concat with tap?

After storing data in the backend, I proceed to retrieve all reserved data for that specific item. It is crucial that the data retrieval happens only after the reservation process to ensure its inclusion. Presented with two possible solutions, I am cont ...

Issue in Typescript: "Implementing Partial is restricted to object types or intersection of object types with known members" error occurs when working with classes

Recently, I encountered an issue with my code that was previously working fine until I updated Typescript: class DefaultRouteConfig implements Partial<RouteConfig> { public meta = { layout: LayoutDefault }; } However, after the update, Typescript ...

Issue with Angular 18 component not being displayed or identified

Recently, I began building an Angular 18 application and encountered an issue with adding my first component as a standalone. It appears that the app is not recognizing my component properly, as it does not display when added as an HTML tag in my app.compo ...

The type 'Requireable<string>' cannot be matched with the type 'Validator<"horizontal" | "vertical" | undefined>'

code import * as React from 'react'; import * as PropTypes from 'prop-types'; interface ILayoutProps { dir?: 'horizontal' | 'vertical' }; const Layout: React.FunctionComponent<ILayoutProps> = (props) => ...

The function in Angular 5/Typescript disappears when attempting to call it from within another function

After importing D3 into my component, I encounter an issue when trying to assign a layout to the D3.layout property. Strangely, although the layout property is present in the console output of my D3 object, it seems to be unknown when I attempt to call i ...

The React Native Flatlist encountered an error due to a mismatch in function overloads

I'm currently working on a React Native app using Typescript, and I've encountered an issue with the Flatlist renderItem function. As someone who is new to both Typescript and React Native, I received the following error message: No overload ma ...

Implementing Microdata with React and Typescript: A Comprehensive Guide

Whenever I include itemscope itemtype="http://schema.org/Product" in h1, an error pops up: The type '{ children: string; itemscope: true; itemtype: string; }' is not compatible with the type 'DetailedHTMLProps<HTMLAttributes<HTMLH ...

Incorrect naming in JSON response from REST API service

Currently, I am in the process of developing a web application using AngularJS and TypeScript with a Netbeans RESTful backend. I have created a TypeScript interface for a vendor which looks like this: interface Vendor { vendorno: number, name: str ...

Mastering the art of constraining TypeScript function parameters using interface properties

Hey there, I've been exploring ways to restrict a function parameter so that it only accepts "strings" related to interface properties, similar to what I achieved in the validate fields function: Please note: The TypeScript code provided here is simp ...