I want to know how to check if "novalue" exist
For example:
{
name: "maria",
city_id: "novalue"
....
}
How i do this in Vue?
Do it in <div v-if="condition"> or function?
In case you want to/can use ES7 features:
const containsKey = (obj, key ) => Object.keys(obj).includes(key);
Implementation example:
const someCoolObject = {name: 'Foo', lastName: 'Bar'};
const hasName = containsKey(someCoolObject, 'name');
const hasNickName = containsKey(someCoolObject, 'hasNickName');
console.log(hasName, hasNickName); // true, false
For Vue:
Component:
{
methods: {
containsKey(obj, key ) {
return Object.keys(obj).includes(key);
}
},
computed: {
hasName() {
return this.containsKey(this.someObject, 'name');
}
}
}
Template:
<div v-if="hasName"></div>
Related
I have an object for validation that might look like this:
const exampleObject = {
foo: {
entries: {
'785bac64-c6ce-4878-bfb8-9cf5b32e2438': {
name: 'First object',
},
'117450da-315b-4676-ad23-edd94a4b6b51': {
name: 'Second object',
},
},
},
}
The keys of the entries object are dynamic (uuids). I want to validate that the name property in any of those objects is not an empty string. However, entries is not required, it is only required that if there are any entries, they cannot contain an empty string. How can I do this with Yup?
const exampleObjectValidation = Yup.object().shape({
foo: Yup.object({
entries: Yup.object({
/* what goes here ? */
})
})
})
Here's how I did it:
const exampleObjectValidation = Yup.object()
.shape({
foo: Yup.object({
entries: Yup.lazy((value) => {
if (!isEmpty(value)) {
const validationObject = { name: Yup.string().required('Item cannot be empty') }
const newEntries = Object.keys(value).reduce(
(acc, val) => ({
...acc,
[val]: Yup.object(validationObject),
}),
{}
)
return Yup.object().shape(newEntries)
}
return Yup.mixed().notRequired()
}),
}),
})
.nullable()
.notRequired()
I have an object (obj), I need to map or loop through the dataToInsert object and display the result as shown in the data object. The complexity is that I need to display part of the name of the object in the field value (FOI_OMG_101 to 101)
const dataToInsert = {
FOI_OMG_101 : {
name : "jghj.pdf",
value: "base64"
}
}
const data=
{
field: "101",
fileName: "jghj.pdf",
value:"base64"
}
this is what I have now
for (const [key, value] of
Object.entries(dataToInsert.FOI_OMG_101)) {
console.log(`${key}: ${value}`);
}
const dataToInsert = {
FOI_OMG_101 : {
name : "jghj.pdf",
value: "base64"
}
};
const data = {
field: "101",
fileName: "jghj.pdf",
value:"base64"
};
// Look at the entries of the full object,
// so you do not have to know the FOI_OMG_101 field name beforehand.
for ([ field, file ] of Object.entries( dataToInsert )) {
console.log( field ); // FOI_OMG_101
console.log( JSON.stringify( file )); // {"name":"jghj.pdf","value":"base64"}
const output = {
field: field,
fileName: file.name,
value: file.value
};
console.log( JSON.stringify( output )); // {"field":"FOI_OMG_101","fileName":"jghj.pdf","value":"base64"}
}
You can add additional string manipulation if you have to parse the number 101 out of the string FOI_OMG_101.
You need to split the key on those objects in the loop, and take the value from the last index of this split key as:
export default function App() {
const dataToInsert = {
FOI_OMG_101: {
name: "jghj.pdf",
value: "base64"
},
FOI_OMG_102: {
name: "abc.pdf",
value: "base64"
}
};
const [arrData, setArrData] = useState([]);
useEffect(() => {
let newArr = [];
Object.keys(dataToInsert).map((keyName, index) => {
const fieldNameArr = keyName.split("_");
newArr = [
...newArr,
{
field: fieldNameArr.at(-1),
fileName: dataToInsert[keyName].name,
value: dataToInsert[keyName].value
}
];
});
setArrData(newArr);
}, []);
useEffect(() => {
console.log("arrData", arrData);
}, [arrData]);
return (
<div className="App">
{arrData.map((item, index) => {
return <li key={index}>{JSON.stringify(item)}</li>;
})}
</div>
);
}
This is just an example of splitting, you can handle it as you wish. Here, is the sandbox link.
I have a Type described in typescript like this -
export type User = {
name: string;
username: string;
phoneNumber: string;
personalEmail?: string;
workEmail?: string
}
I'm fetching some data from a json file which consists of objects like these and shaping the data to this type User for each object with this function
const shaper = (obj: any): User {
const user: User = {
name: obj.name,
username: obj.username,
number: obj.number,
personalEmail: obj.personalEmail,
workEmail: obj.workEmail,
}
// remove from user the fields which have value === undefined
return user;
}
In the shaper function, I want to remove the fields of the variable user which have the value as undefined (eg : obj.personalEmail does not exist)
How do I achieve this?
Here you have a working example.
You can use delete obj[key]
const shaper = (obj) => {
const user = {
name: obj.name,
username: obj.username,
number: obj.number,
personalEmail: obj.personalEmail,
workEmail: obj.workEmail,
}
Object.entries(user).forEach(([key, value]) => {
if (value === undefined) {
delete user[key];
console.log("deleted", key);
}
});
return user;
}
const shapedResult = shaper({
name: "foo",
workEmail: "bar#bar.com"
});
console.log(shapedResult);
You could do something like this:
/* Test Data */
const test = {
name: 'name',
username: 'username',
needToRename: '123456789',
another: 'blah',
something: 'else',
workEmail: 'hello#example.com'
}
/* Example 1 */
const shaper = ({name, username, needToRename:phoneNumber, personalEmail, workEmail}) => {
return {
name,
username,
phoneNumber,
...( personalEmail !== undefined && {personalEmail} ),
...( workEmail !== undefined && {workEmail})
}
}
console.log(shaper(test));
Or you could extract the undefined check into a helper function and do this:
/* Test Data */
const test = {
name: 'name',
username: 'username',
needToRename: '123456789',
another: 'blah',
something: 'else',
workEmail: 'hello#example.com'
}
/* Example 2 */
function undefinedHelper(name, obj) {
return obj[name] === undefined ? {} : {[name]: obj[name]};
}
const shaper2 = (obj) => {
return {
name: obj.name,
username: obj.username,
phoneNumber: obj.needToRename,
...undefinedHelper('personalEmail', obj),
...undefinedHelper('workEmail', obj)
}
}
console.log(shaper2(test));
This answer was helpful: https://stackoverflow.com/a/40560953/2344607
I've got a method for generate url
But I have a little problem when I'm adding the condition if/else, he returns me only the first value and not all
This is my code :
public generateUrl(components: any, versions: any) {
const keys: any[] = Object.keys(components); //['toto','titi','tata','tutu']
for (const component of keys) {
const versions = components[component].artifacts.map((arti) => {
return {
component: arti.name,
type: arti.type,
version: versions[arti.name],
};
});
console.log(versions); // Display only the first one and not all
//[ { component: 'toto',
// type: 'npm',
// version: '1' } ]
for (const i in versions) {
const v = versions[i];
// here i'm adding the confition
if (v.type === "jar") {
const urlTest =
v.component +
"/" +
v.version +
".jar"
return urlTest;
} else if (v.type === "npm") {
const urlTest =
v.component +
"/" +
v.version +
".npm"
return urlTest;
}
} else if (v.type === "rpm") {
const urlTest =
v.component +
"/" +
v.version +
".rpm"
return urlTest;
}
}
}
}
}
I need to retrieve all values and not only the first one.
THanks for your help
Use Array.prototype.reduce to accumulate your values which match up to your type, instead of returning after match.
Also the for-in loop is to enumerate over enumerable object properties of a object, if I am not mistaken then versions is an array.
Working example below -
const data = [
{
component: 'toto',
type: 'npm',
version: '1'
},
{
component: 'tata',
type: 'jar',
version: '2'
},
{
component: 'titi',
type: 'rpm',
version: '3'
}
];
const types = ['npm', 'jar', 'rpm'];
const testUrls = data.reduce((acc, { component, type, version }) => {
if (types.includes(type)) {
acc.push(`${component}/${version}.${type}`);
}
return acc;
}, []);
console.log(testUrls);
like #Bergi said
That's because you return from the first iteration of the loop.
else you can try something like that, by using reduce:
Working example:
type Component = {
artifacts: any[];
};
type Version = {
[key: string]: string;
}
class Test {
public static GenerateUrl(components: Component[], versions: Version) {
return components.reduce((acc: any, { artifacts }) => {
return artifacts.reduce((acc, { type, name }) => {
acc.push(`${name}#${versions[name]}.${type}`);
return acc.flat();
}, acc);
}, []);
}
};
const versions: any = {
"titi": "1.0.0",
"toto": "1.8.1",
"tata": "1.2.5"
}
const components = [
{
artifacts: [
{
type: "jar",
name: "titi"
},
{
type: "npm",
name: "titi"
},
{
type: "rpm",
name: "toto"
},
{
type: "rpm",
name: "tata"
}
]
}
]
console.log(Test.GenerateUrl(components, versions)); // ["titi#1.0.0.jar","titi#1.0.0.npm","toto#1.8.1.rpm","tata#1.2.5.rpm"]
I have an array of objects like this:
const data = [{
_id:"49847444033",
name:"yoko"
},{
_id:"49847433333",
name:"doira"
}]
I have to change each item name property to something like this :
...
{
_id:"49847433333",
name:{
en:"John"
}
}
My attempt is to loop object like following :
data.forEach((item) => {
item.name = {en:"john"}
console.log(item)
})
But this always console the original item and the name property value is not modified.
const newData = data.map(user => ({ _id: user._id, name: { en: user.name } }))
I created a library to express transformations like this very simply.
const { pipe, fork, get } = require('rubico')
const data =
[ { _id: '49847444033', name: 'yoko'}
, { _id: '49847433333', name: 'doira'}
]
const onData = pipe([
fork({
_id: get('_id'), // data => data._id
name: fork({ en: get('name') }), // data => ({ en: data.name })
}),
console.log,
])
data.map(onData) /*
{ _id: '49847444033', name: { en: 'yoko' } }
{ _id: '49847433333', name: { en: 'doira' } }
*/
I've commented the code above, but to really understand rubico and get started using it, I recommend you read the intuition and then the docs
try somthing like:
const newList = data.map(obj => {
return { _id: obj._id, name: { en: obj.name } }
});
and the newList list is your new data list so you can do it:
data = newList;
EDIT:
if you have more properties you can change the return line to:
return { ...obj, name: { en: obj.name } }
what will happen here, it will deploy all the object properties as they are, and modify the name property, unfortunately, every property you want to modify, you have to re-write it.