Replace base64 images by uploaded urls of a nested object - javascript

I have data like this:
const currentData = {
id: "u76u76h",
type: "cardA",
name: "Section 1",
thumbnail: {
src: "",
alt: "",
},
data: {
avatar: {
dataType: "image",
src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBXgFy56y56y56",
alt: "avatar"
},
album: [
{
dataType: "image",
src: "https://firebasestorage.googleapis.com/album_image1.png",
alt: "album_image1"
},
{
dataType: "image",
src: "https://firebasestorage.googleapis.com/album_image2.png",
alt: "album_image2"
}
],
cards: [
{
icon: {
dataType: "image",
src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBXgF",
alt: "card_image1"
},
title: "新規事業企画担当",
description: [
"企画書だけでは、「新しいビジネスの良さを理解してもらう事」が難しい!",
"アイディアを実際に使ってもらって実感してもらいたい!"
]
}
]
}
};
I want to extract all the base64 urls (none https) and upload to cloud storage, and after uploaded the storage I want to update the uploaded urls to the data object above before saving the data object to the database. But the problem is the data structure is complicated and can be 2 or 3 or more in nested level. I am scratching my head to find a solution. Please help me!

You can use recursion to view the whole object. Be careful if the object contains circular references.
And remove isBase64Fake function. Use isBase64 instead. I've added isBase64Fake only to check your object.
function extractBase64(data) {
const result = [];
Object.keys(data).forEach((key) => {
if (typeof data[key] === 'string') {
isBase64Fake(data[key]) && result.push({
data,
key,
value: data[key]
});
} else if (typeof data[key] === 'object') {
result.push(...extractBase64(data[key]));
}
});
return result;
}
function uploadSomewhere(dataToUpload) {
console.log('uploading...');
setTimeout(() => {
dataToUpload.forEach((item) => {
item.data[item.key] = 'QWERTY';
});
}, 1000);
}
function isBase64Fake(str) {
return /^data:/.test(str);
}
function isBase64(str) {
if (!str) {
return false;
}
try {
window.atob(base64);
result = true;
} catch (e) {
result = false;
}
}
const currentData = {
id: "u76u76h",
type: "cardA",
name: "Section 1",
thumbnail: {
src: "",
alt: "",
},
data: {
avatar: {
dataType: "image",
src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBXgFy56y56y56",
alt: "avatar"
},
album: [{
dataType: "image",
src: "https://firebasestorage.googleapis.com/album_image1.png",
alt: "album_image1"
},
{
dataType: "image",
src: "https://firebasestorage.googleapis.com/album_image2.png",
alt: "album_image2"
}
],
cards: [{
icon: {
dataType: "image",
src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBXgF",
alt: "card_image1"
},
title: "新規事業企画担当",
description: [
"企画書だけでは、「新しいビジネスの良さを理解してもらう事」が難しい!",
"アイディアを実際に使ってもらって実感してもらいたい!"
]
}]
}
};
const dataToUpload = extractBase64(currentData);
console.log(dataToUpload);
uploadSomewhere(dataToUpload);
setTimeout(() => console.log(currentData), 2000);

Related

Sanity CMS and Leaflet.Js while using geolocation API

I have created a sanity schema which works perfectly according to the tutorial. However I have a leaflet.js plugin and I am trying to get it to auto find my location when I create a new template in the sanity studio. This was already done in the tutorial below, but when I do it, I get the sanity map showing up but I do not get the marker on my current location. Instead I get the default San-Francisco.
In the tutorial the lady gets allows the browser to share her location. However I do not get that prompt. Is this something to do with localhost?
I am following this tutorial but I don't know what I missed.
Relevant parts from 31.00-37.00. Tutorial below:
https://www.youtube.com/watch?v=YtFfUER8ta8
Below is my posts.js
const getPosition = (options) => {
if (navigator.geolocation) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, options);
});
}
};
export default {
name: "post",
title: "Blog Post",
type: "document",
initialvalue: async () => ({
postedAt: await getPosition()
.then(({ coords }) => {
const { latitude, longtitude, altitude } = coords;
return {
_type: "geopoint",
lat: latitude,
lng: longtitude,
alt: altitude || undefined,
};
})
.catch(() => undefined),
}),
fields: [
{
name: "title",
title: "Title",
type: "string",
},
{
name: "postedAt",
type: "geopoint",
title: "Location",
},
{
name: "slug",
title: "Slug",
type: "slug",
options: {
source: "title",
maxLength: 96,
},
},
{
name: "author",
title: "Author",
type: "reference",
to: { type: "author" },
},
{
name: "mainImage",
title: "Main image",
type: "image",
options: {
hotspot: true,
},
},
{
name: "categories",
title: "Categories",
type: "array",
of: [{ type: "reference", to: { type: "category" } }],
},
{
name: "publishedAt",
title: "Published at",
type: "datetime",
},
{
name: "body",
title: "Body",
type: "blockContent",
},
],
preview: {
select: {
title: "title",
author: "author.name",
media: "mainImage",
},
prepare(selection) {
const { author } = selection;
return Object.assign({}, selection, {
subtitle: author && `by ${author}`,
});
},
},
};
leaflet-input.json
{
"tileLayer": {
"attribution": "© OpenStreetMap contributors",
"url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
}
}

run function with uniquie value using javascript / node js

let object=
[
{
id:`01`,
name:`fish`,
type:null,
care:'owner',
},
{
id:`02`,
name:`fish`,
type:'fresh',
care:'peter',
},
{
id:`03`,
name:`fish`,
type:`fresh`,
care:'amy',
},
{
id:`04`,
name:`fish`,
type:`tank`,
care:'abc',
},
{
id:`05`,
name:`animal`,
type:`pet`,
care:'teen',
},,
{
id:`06`,
name:`animal`,
type:`pet`,
care:'ran',
},
{
id:`07`,
name:`animal`,
type:null,
care:'roh',
},
{
id:`08`,
name:`food`,
type:`veg`,
care:'test',
},
{
id:`09`,
name:`food`,
type:null,
care:'dop',
}
]
object.map((value)=>{
console.log(value.name)
// i am calling function here by passing value.name as a parameter
let gotValue = functionName(value.name);
// using type also
if(typeof value.type!=="string"){
// Do some task here with gotValue
}
})
I have this object and i am getting some value from it for ex getting name from it as i want to pass this name to function but the problem is due to repeat of data the function calling again and again is there any possibility i can run function inside map but with unique value any help ?
as my output is getting like this
fish
fish
fish
animal
animal
animal
and this value.name is passing inside my function so its repeating like this
functionName(fish);
functionName(fish);
functionName(fish);
functionName(animal);
functionName(animal);
functionName(animal);
multiple time function is running with same name and getting duplicate values
just need my function run with unique name
functionName(fish)
functionName(animal);
functionName(food);
as i want to stay inside map function because i am performing some task which can only be possible inside map that's why i need unique value
You can use Set which can be used to test if the object with value already exists or not. It will only call the function only once.
let object = [
{
id: `01`,
name: `fish`,
type: null,
},
{
id: `02`,
name: `fish`,
type: `fresh`,
},
{
id: `03`,
name: `fish`,
type: `tank`,
},
{
id: `04`,
name: `animal`,
type: `pet`,
},
{
id: `05`,
name: `animal`,
type: `wild`,
},
{
id: `06`,
name: `animal`,
type: null,
},
{
id: `07`,
name: `food`,
type: `veg`,
},
{
id: `08`,
name: `food`,
type: null,
},
];
const dict = new Set();
object.map((value) => {
if (!dict.has(value.name)) { // Run only if objet with name is not already existed in dict
dict.add(value.name);
console.log(value.name); // For testing
// functionName(value.name);
}
});
If you want to call the function with two filters then you can use some to find the elements in an array. See I've now declared dict as an array
let object = [{
id: `01`,
name: `fish`,
type: null,
},
{
id: `02`,
name: `fish`,
type: `fresh`,
},
{
id: `03`,
name: `fish`,
type: `tank`,
},
{
id: `04`,
name: `animal`,
type: `pet`,
},
{
id: `05`,
name: `animal`,
type: `wild`,
},
{
id: `06`,
name: `animal`,
type: null,
},
{
id: `07`,
name: `food`,
type: `veg`,
},
{
id: `08`,
name: `food`,
type: null,
},
{
id: `09`,
name: `food`,
type: null,
},
{
id: `10`,
name: `fish`,
type: `tank`,
},
];
const dict = [];
object.map((value) => {
const { name, type } = value;
if (!dict.some((obj) => obj.name === name && obj.type === type)) {
// Run only if objet with name is not already existed in dict
dict.push({ name, type });
console.log(name, type); // For testing
// functionName(value.name);
}
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

Vue how push object with specific key to array

I'm working on an vue-application where I have a component for driving licenses.
I have the following:
data() {
return {
custom_licenses: [],
basic_licenses: []
}
}
within my methods, I have this:
regular_licenses() {
this.$store.dispatch("license/read").then(response => {
response.licenses.map((license, key) => {
// PUSH LICENSES WITH TYPE 'BASIC' TO this.basic_licenses
// PUSH LICENSES WITH TYPE 'CUSTOM' TO this.custom_licenses
});
});
},
and in my created() i have this:
created() {
this.regular_licenses()
}
The response from my dispatch, returns this:
licenses:
[
{
id: 1,
type: 'basic',
name: 'AMa'
},
{
id: 2,
type: 'basic',
name: 'A2'
},
{
id: 3,
type: 'basic',
name: 'C'
},
{
id: 4,
type: 'custom',
name: 'C1'
},
{
id: 5,
type: 'custom',
name: 'D'
},
and so on...
]
Now I want to loop through the array and separate or push them into custom_licenses and basic_licenses based on the type-attribute - how can I achieve that?
Try this
regular_licenses() {
this.$store.dispatch("license/read").then(response => {
response.licenses.map((license, key) => {
switch (license.type)
case 'basic':
this.basic_licenses.push({ ...license });
break;
case 'custom':
this.custom_licenses.push({ ...license });
break;
});
});
},
Update your Code Block:
response.licenses.map((license, key) => {
// PUSH LICENSES WITH TYPE 'BASIC' TO this.basic_licenses
if(license['type'] == 'basic') {
//deep clone
let tmpLicense = JSON.parse(JSON.stringify(license));
basic_licenses.push(tmpLicense);
} else if(license['type'] == 'custom') {
// PUSH LICENSES WITH TYPE 'CUSTOM' TO this.custom_licenses
//deep clone
let tmpLicense = JSON.parse(JSON.stringify(license));
custom_licenses.push(tmpLicense);
}
});

form Data set values from web service response

I am trying to set table values from webservice response.
Iam getting my web service response like this.but if he response is like this means it is not getting set there.This response can be dynamic.
0:{name: "image.png", base64: "iVBORw"}
1:{name: "download.png", base64: "iVBO"}
2:{name: "test-animation.gif", base64: "R0lGODlhLAEs"}
How can i change it to??
[["image.png", "iVBORw"],["download.png", "iVBO"],[test-animation.gif", "R0lGODlhLAEs"]]
here it is what iam trying
$.cordys.ajax({
method: "somewebservice",
namespace: "Package",
parameters: {
emailid:mailidvalue
},
dataType: '* json',
success: function (result) {
output=result;
bodycontent=output["data"]["body"];
var attachvalue=result.data.tuple;
$('#attachmenttable').DataTable( {
"data": attachvalue,
columns: [
{ title: "File Name" },
{ title: "Base64" }
]
} );
},
error: function(err){
console.log(err);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
I see a 1-1 mapping between what you are given and what you desire, therefore use Array.prototype.map() or $.map.
var given = {
0: {
name: "image.png",
base64: "iVBORw"
},
1: {
name: "download.png",
base64: "iVBO"
},
2: {
name: "test-animation.gif",
base64: "R0lGODlhLAEs"
}
};
var desired = Object.keys(given).map(function(key) {
return [ given[key].name, given[key].base64 ];
});
console.log(desired);
var given = {
0: {
name: "image.png",
base64: "iVBORw"
},
1: {
name: "download.png",
base64: "iVBO"
},
2: {
name: "test-animation.gif",
base64: "R0lGODlhLAEs"
}
};
var desired = $.map(given, function (value, key) {
return [[ given[key].name, given[key].base64 ]];
});
console.log(desired);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

How to merge two object with different properties

I have something like this :
let user = [
{
name: "step-one",
values: {companyName: "Name", address: "company address"}
},
{
name: "step-two",
values: {name: "User", mobile: 0123}
},
{
name: "step-three",
values: [
{file: "companyLogo", values: {active: true, fileName: "some name"}},
{file: "avatar", values: {active: true, fileName: "file name"}}
]
}
]
I want to get only values and put them into a new object. Thus, something like :
let wantedResult = {
companyName: "Name",
address: "company address",
name: "User",
mobile: 0123,
files: [
{file: "companyLogo", values: {active: false, fileName: "some name"}},
{file: "avatar", values: {active: false, fileName: "file name"}}
]
};
Any advice how I can do that?
You can try this!
let user = [{
name: "step-one",
values: {
companyName: "Name",
address: "company address"
}
}, {
name: "step-two",
values: {
name: "User",
mobile: 0123
}
}, {
name: "step-three",
values: [{
file: "companyLogo",
values: {
active: true,
fileName: "some name"
}
}, {
file: "avatar",
values: {
active: true,
fileName: "file name"
}
}]
}]
var wantedResult = Object.assign({}, user[0].values, user[1].values, {files: user[2].values})
console.log(wantedResult)
It is a bit hacky because of the files array, but i would do it like that:
var wantedResult = user.reduce((result, step) => {
var values = Array.isArray(step.values) ? { files: step.values } : step.values;
return Object.assign({}, result, values)
}, {});
Of course it'll work only for that kind of structure you provided. If you have more objects that have an array in the 'values' property, you'll need to rethink the approach.
Step 3 is inconsistent with the others. If possible, make it consistent to have: values: files: [ { file1_data }, { file2_data } ].
After fixing the inconsistency, you can iterate through each of the steps and add the new properties to the result.
let wantedResult = user.reduce(function(result, spec) {
Object.keys(spec.values).forEach(function(key) {
result[key] = spec.values[key];
});
return result;
}, {});
If not possible to change step 3, you can make it a bit less clean:
let wantedResult = user.reduce(function(result, spec) {
if (spec.name === "step-three") {
result.files = spec.values;
}
else {
Object.keys(spec.values).forEach(function(key) {
result[key] = spec.values[key];
});
}
return result;
}, {});

Categories