How to insert an Image URL for Images stored in Postgres into a Spring Boot Model - arrays

I have built an app with a Spring Boot Gradle Kotlin Backend, that can store and upload Multipart files to a Postgres database. The data is stored in a ByteArray. So far everything is working fine.
Now I want to add an Image URL to make it available in my JSON Object to later grab it and display it on my client side like the ones on Unsplash.
imageURL
"imageURL": "https://xyz.jpg"
File model
#Entity
#Table(name = "file")
data class File(
#Id
val id: UUID = UUID.randomUUID(),
val createdAt: LocalDateTime = LocalDateTime.now(),
var updatedAt: LocalDateTime = LocalDateTime.now(),
var likes: Int = 0,
var likedByUser: Boolean = false,
var description: String = "",
val downloadLink: URI = URI("https://unsplasy-backend.herokuapp.com/files/download/$id"),
var name: String = "",
var type: String = "",
#Basic(fetch = FetchType.LAZY)
private val data: ByteArray = byteArrayOf(),
val imageURL: TODO = "TODO"
)
Store
fun store(file: MultipartFile): File {
val fileName = file.originalFilename.toString()
val fileToSave = File(
name = fileName,
type = file.contentType.toString(),
data = file.bytes
)
return fileRepository.save(fileToSave)
}

After reading the suggestion above I came up with this and it works.
Controller Update
#GetMapping("/files/image/{id}")
fun displayImage(#PathVariable id: UUID, response: HttpServletResponse) {
val file = fileService.getFile(id)
val data = fileService.getData(file)
response.contentType = file.type
response.outputStream.write(data)
response.outputStream.close()
}
File Model update
val imageURL: URL = URL("https://unsplasy-backend.herokuapp.com/files/image/$id"),

Related

How do I declare an array of json in kotlin

I'm a beginner with kotlin and Android Studio and I'm trying to declare a json array in a data class. This class is used to store data that I get from my api, but the Json is a bit complex and I dont know how to declare an array of Json with moshi.
Here is my Json:
{
_id : String,
name : String,
type : String,
stateList : [{
date: Integer,
source : String,
variables:[{
name: String,
value: String,
}]
}]
}
and here is my attempt:
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.baseUrl(BASE_URL)
.build()
interface MyApiService {
#GET("allDevice")
fun getProperties(): Deferred<List<Device>>
}
object MyApi {
val retrofitService : MyApiService by lazy { retrofit.create(MyApiService::class.java) }
}
class State(
#Json(name = "date") val date: Integer,
#Json(name = "source") val source: String,
val stateList: List<variable>)
class variable(
#Json(name = "name") val name: String,
#Json(name = "value") val value: String
)
data class Device(
val _id: String,
val stateList: List<State>,
val type: String,
val name: String)
I guess that this is not the good way to declare my Json so what is the proper way to do it?
I think you should change class State to something like this (match variable name with json atribute name):
class State(
#Json(name = "date") val date: Integer,
#Json(name = "source") val source: String,
val variables: List<variable>
)

why? error: Cannot figure out how to save this field into database

I stuck with a fool issue
I have response from server
data class AddressResponse(
#SerializedName("message") val responseMessage: String,
#SerializedName("success") val success: Int,
#SerializedName("status") val status: Int,
#SerializedName("data") val data: Data
) {
data class Data(
#SerializedName("id") val addressId: Long,
#SerializedName("status") val status: Int?,
#TypeConverters( CommunicationPropertiesConverter::class )
#SerializedName("communication_properties") val communicationProperties: AddAddressRequest.CommunicationProperties?,
#SerializedName("more_information") val moreInformation: String?
) {
data class CommunicationProperties(
#SerializedName("par1") var par1: Boolean,
#SerializedName("par2") val par2: Boolean,
#SerializedName("par3") val par3: Boolean,
#SerializedName("par4") val par4: Boolean
)
}
}
I use room and I have entity class
#Entity(tableName = "db_address")
data class DbAddress(
#PrimaryKey #ColumnInfo(name = COLUMN_ID) val id: Long,
#ColumnInfo(name = COLUMN_STATUS) val status: Int?,
#TypeConverters(CommunicationPropertiesConverter::class)
#ColumnInfo(name = COLUMN_COMM_PROPS) val communicationProperties: AddressResponse.Data.CommunicationProperties,
#ColumnInfo(name = COLUMN_MORE_INFO) val moreInfo: String?
)
I have a convertor a set annotations #TypeConverters & #TypeConverter
class CommunicationPropertiesConverter {
private val gson = Gson()
#TypeConverter
fun toCommunicationProperties(mString: String?): AddressResponse.Data.CommunicationProperties {
if (mString.isNullOrEmpty())
return AddressResponse.Data.CommunicationProperties(par1 = false, par2 = false, par3 = false, par4 = false)
val listType = object : TypeToken<AddressResponse.Data.CommunicationProperties>(){}.type
return gson.fromJson(mString, listType)
}
#TypeConverter
fun fromCommunicationProperties(properties: AddressResponse.Data.CommunicationProperties?): String {
if (properties == null)
return "0000"
return gson.toJson(properties)
}
}
but I still get an error
error: Cannot figure out how to save this field into database. You can
consider adding a type converter for it
private final ... AddressResponse.Data.CommunicationProperties communicationProperties = null
but I added converter to and from "primitive" type
why? what did I forget?
I had a similar issue and what worked for me was annotating that field (that has the custom type) with #Embedded. In my case, I didn't even need type converters anymore.

How to handle data and data models in SwiftUI

I am having trouble with the structure of my data for creating a List in SwiftUI. Before SwiftUI I created my data models and held this data in separated files. For example,
In my UserModel.swift :
import SwiftUI
struct UserModel: Equateable {
var name: String
var items = [ItemModel]()
init(name: String, items: [ItemModel]? = nil) {
self.name = name
if let items = items {
self.items = items
}
}
}
In my ItemModel.swift :
import SwiftUI
struct ItemModel: Equatable {
var itemName: String
var price: Double
init(itemName: String, price: Double) {
self.itemName = itemName
self.price = price
}
}
Then I had a separate class called Data that held this data.
In my Data.swift :
import Foundation
class Data {
static var userModels = [UserModel]()
static var itemModels = [ItemModel]()
}
I would update the data by doing something like this in my views:
let user = UserModel(name: "Bob")
Data.userModels.append(user)
I'm having trouble populating a List from this framework in SwiftUI. I tried to make both of my model classes conform to Identifiable but that doesn't seem to help in updating the list. This is what I'm doing so far:
Updated UserModel :
struct UserModel: Identifiable {
var id = UUID()
var name: String
var items = [ItemModel]()
init(id: UUID, name: String, items: [ItemModel]? = nil) {
self.id = id
self.name = name
if let items = items {
self.items = items
}
}
}
Updated ItemModel:
struct ItemModel: Identifiable {
var id = UUID()
var itemName: String
var price: Double
init(id: UUID, itemName: String, price: Double) {
self.id = id
self.itemName = itemName
self.price = price
}
}
And in my ContentView.swift
List (Data.userModels) { user in
Text("\(user.name)")
}
But this does not update the List when I am running the app. (Btw I take input from TextField, append it to Data.userModels, and try to populate it in the List with no luck.)
Is there a different way I should be structuring my data and data models? Or am I just not using the proper syntax when creating the list? Sorry for the long question. Thanks for the help!

Sending an array of String and receive it using parcelable kotlin

i been trying to send up an array of string using parcel in kotlin, i tried several things like converting to array before using writeTypedArray, or directly using writeStringArray. I also tried to read using createTypedArray and createdStringArray.
For most of the case, the content i receive is right ( i mean the inside of the array does not change ), but there is some case where it becomes a nulls and some link in the array.
I have checked my code, and print it before and after the usage of intent, and thats where the difference is, so i guess the fault lies in the parcel
This is the place where i put my intent, when i call showGenres(), its show
the exact genres like Comedy and Slice of Life
val anime : Anime = news.anime
val intent : Intent = Intent(holder.btnViewMore.context, DetailActivity::class.java)
news.anime.showGenres()
intent.putExtra("choosen", anime)
holder.btnViewMore.context.startActivity(intent)
but, after i receive the intent, when i call the showGenres, the content become nulls (most of them) and some string like "P��https://s4.anilist.co/file/anilistcdn/media/anime/banner/104199-ha1rxhhOb8Yp.jpg��������Comedy������Slice".
anime = intent.getParcelableExtra("choosen")
anime.showGenres()
enter image description here
Below are my class which use parcellable
package com.example.jnimekuy.Model
import android.os.Parcel
import android.os.Parcelable
import android.util.Log
class Anime(
var id: Int = 0,
var title: String? = "",
var image: String? = "",
var description: String? = "",
var status: String? = "",
var startDate: String? = "",
var endDate: String? = "",
var season: String? = "",
var episode: Int? = 1,
var duration: Int? = 1,
var trailer: String? = "",
var cover: String? = "",
var banner: String? = "",
var genreList: List<String>? = ArrayList(),
var avgScore: Float? = 1F
):Parcelable{
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readString(),
parcel.readString(),
parcel.readString()?.replace("<br>","",true),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.readInt(),
parcel.readInt(),
parcel.readString(),
parcel.readString(),
parcel.readString(),
parcel.createStringArrayList()?.filterNotNull(),
parcel.readFloat()
)
override fun writeToParcel(parcel: Parcel, p1: Int) {
parcel.writeInt(id)
parcel.writeString(title)
parcel.writeString(image)
parcel.writeString(description)
parcel.writeString(status)
parcel.writeString(startDate)
parcel.writeString(endDate)
parcel.writeString(season)
episode?.let { parcel.writeInt(it) }
duration?.let { parcel.writeInt(it) }
parcel.writeString(trailer)
parcel.writeString(cover)
parcel.writeString(banner)
parcel.writeStringList(genreList)
avgScore?.let { parcel.writeFloat(it) }
}
fun showGenres(){
for(i in this!!.genreList!!)
{
Log.d("genre",i)
}
}
override fun describeContents(): Int {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
companion object CREATOR : Parcelable.Creator<Anime> {
override fun createFromParcel(parcel: Parcel): Anime {
return Anime(parcel)
}
override fun newArray(size: Int): Array<Anime?> {
return arrayOfNulls(size)
}
}
}
Ok, i found the problem, because i use let , which is if not null then send something, then if its null, it does not send anything, but still get opened by parcel constructor. There is nothing wrong with the write and type string array.
what i did was to put if null then still send something
parcel.writeInt(id)
parcel.writeString(title)
parcel.writeString(image)
parcel.writeString(description)
parcel.writeString(status)
parcel.writeString(startDate)
parcel.writeString(endDate)
parcel.writeString(season)
if(episode != null){ parcel.writeInt(episode!!) }
else { parcel.writeInt(0) }
if(duration != null){ parcel.writeInt(duration!!) }
else { parcel.writeInt(0) }
parcel.writeString(trailer)
parcel.writeString(cover)
parcel.writeString(banner)
parcel.writeStringList(genreList)
avgScore?.let { parcel.writeFloat(it)

Collection is not getting created even after creating the model using mongoose

I have created a model using mongoose.
However, it is not creating collection in mongodb.
My connection is working fine though to the mongodb
var mongoose = require("mongoose"),
Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
const conn = require('app/connection');
var notesSchema = new Schema({
_id: ObjectId,
message: String,
});
var dataSchema = new Schema({
_id: ObjectId,
dataId: String,
dataName: String,
notes: [notesSchema]
}, {
collection: 'dataCols'
});
var dataCol = conn.on('cg').model('dataCol', dataSchema);
I have also tried acting against the model (find, insert etc) but the collection is not created automatically.
I am connecting to a replica set

Resources