Cant load content – TypeError: Cannot read properties of null (reading 'attributes‘) - vue.js

currently working on an issue and cant figure out why my page throws me an error.
Having this component:
<JobDetailSectionText
:variant="tmpl({ red: 1, blue: 4, yellow: 7 })"
:image-src="
jobProfile.attributes.imagePractice
? $strapi.options.url +
jobProfile.attributes.imagePractice.data.attributes.url
: '/static/img/praxisteil.jpg'
"
:image-alt="
jobProfile.attributes.imagePractice.data.attributes.alternativeText
"
>
In my content manager in Strapi I changed the „attribute.imagePractice" from required = true to false and now want to, if no file is added to the database show a default image in '/static/img/praxis.jpg‘.
But the console of the page gives me an error
"TypeError: Cannot read properties of null (reading 'attributes')
I tried to figure out the source of the problem but the page only works if I add and imagePractice in the backend, it won’t take the default img I tried to declare with the static path.
Any thoughts?
Thanks!

You can use optional chaining to check if property is exist
<JobDetailSectionText
...
jobProfile.attributes?.imagePractice
? $strapi.options.url +
jobProfile.attributes.imagePractice.data.attributes.url
: '/static/img/praxisteil.jpg'
"
...
>

#DinhTX solution is good, but note, that you cannot use optional chaining unless it's Vue 3. Read more here.
If you're using Vue version less then 3 you would need to write a computed property for that src attribute value where you'd check if attributes exist. Actually, I'd recommend you to use computed property anyway cause Vue's templates should be more HTML and less JS (not like React).
Example of computed property would be:
computed: {
jobSrc() {
const strapiUrl = `${$strapi.options.url}${jobProfile.attributes.imagePractice.data.attributes.url}`
return jobProfile.attributes?.imagePractice ? strapiUrl :'/static/img/praxisteil.jpg'
}
}

Related

Override/change name of fields in JSON response in API Platform

I am working on an API Platform 3 (Symfony 6) app.
In my JSON response, I have the following :
{
...
"totalItems": 7065,
"itemsPerPage": 10,
...
}
Is it possible to change the config so that I get :
{
...
"total_items": 7065,
"page_size": 10,
...
}
So basically I want to rename these fields, in the response I get. Is it possible ?
If your question is about parameter names for pagination only, so then you can just execute bin/console debug:config api_platform and you will see available config parameters (documentation) under api_platform.collection.pagination:
collection:
pagination:
page_parameter_name: page
items_per_page_parameter_name: perPage
enabled: true
partial: false
client_enabled: false
client_items_per_page: false
client_partial: false
items_per_page: 30
maximum_items_per_page: null
enabled_parameter_name: pagination
partial_parameter_name: partial
Hope you will find what you want. Anyway, you can always to find the place where this piece is serialized and try to decorate/override it.
Otherwise, if you want to change the name of some another parameter from api resource you can use SerializedName() attribute on this property
The custom normalizer is the solution to this question.
A custom event listener is also a solution but it is not GraphQL friendly.

GoodData charts components throwing error of TypeError: item.predicate is not a function on setting color from configuration

On setting colors from configuration and using Gooddata UI Charts component it is throwing following error
TypeError: item.predicate is not a function
My config is as follows, On reseting default color it is working fine but as change color i get the colorMapping object in the api and after applying this config throwing the error.
How can i resolve it, Please help me out.
config={{
colorMapping: [{
color: { type: "guid", value: "17" },
id:"0d447449c2844b228923c37de7b6aaf9"
}]
}}
usage of ColorMapping is described in documentation
https://sdk.gooddata.com/gooddata-ui/docs/chart_config.html#Color-mapping
You need to define predicate function which when returning true, will apply corresponding color (https://sdk.gooddata.com/gooddata-ui/docs/ht_create_predicates.html).
In your case localId predicate seems to be right for you
https://github.com/gooddata/gooddata-ui-sdk/blob/master/libs/sdk-ui/src/base/headerMatching/HeaderPredicateFactory.ts#L264
In case you are using older version of Gooddata UI.SDK than v8, you need to implement predicate by your own. Something like this (or equivalent for measures).
predicate: headerItem =>
headerItem.attributeHeaderItem &&
headerItem.attributeHeaderItem.localIdentifier === "0d447449c2844b228923c37de7b6aaf9", // find attribute item by localIdentifier
You can switch the official documentation to whathever version of Gooddata UI.SDK lib you are using and read the same article about ColorMapping
https://sdk.gooddata.com/gooddata-ui/docs/7.9.0/chart_config.html#color-mapping

Avoid converting null to empty string on b-input blur

I'm facing an issue with reactivity in Vue JS 2.6.6. Not sure if it's an issue at all or I'm missing something here.
I'm hydrating an object from MySQL DB through axios getting:
resource:Object
id: 123
alt: null
file:"2a72d890d0b96ef9b758784def23faa1.jpg"
type:"jpg"
}
The form is handling the properties via v-model:
<b-input v-model="resource.alt" />
What I can see is that on blur event, besides no changes were made, the resource.alt property is being changed from null to an empty string ""
resource:Object
id: 123
alt: ""
file:"2a72d890d0b96ef9b758784def23faa1.jpg"
type:"jpg"
}
So what could be the best way to handle this? I don't think that fetching all null fields from DB as empty strings is a nice solution. I mean something like IFNULL(files.alt,'') AS alt
On the other hand, since I fetch a lot of records by doing a loop through them all and setting all null properties to empty string looks very inefficient.
What I need is to keep null properties as null or parse in some way all null properties to empty string from the beginning.
FYI, I'm using vee-validate, so I need to validate if the object has changed with pristine flag which is set to false if the object has been manipulated. This behavior is setting the flag to false because of the change from null to ""
EDIT
This is getting odd. The way I propagate the resource to local data in the component is by clicking an element from a list.
data: () => ({
files: [],
resource: {}
})
<div v-for="file in files" :key="file.id"
#click.exact="handleIndividualCheck(file)">
{{ file.file }}
</div>
methods: {
handleIndividualCheck (item) {
this.resource = { ...item }
}
}
The first time I select an item, the null property is converted to an empty string as explained.
The next times, everything works as expected
This is in fact a bootstrap-vue bug for version 2.19.0
I've reported the issue and fixes will be merged in the next release.
Link to issue: https://github.com/bootstrap-vue/bootstrap-vue/issues/6078

ERROR TypeError: Cannot read property 'project_name' of undefined - Angular 8

My ts code coding is,
this.api.getPay(this.donationId).subscribe(
data => {
this.paymentData = data;
this.paymentDetails = this.paymentData.donationDetails[0];
}
)
My html code is like
Project : <strong>{{paymentDetails.project_name}}</strong><br/>
Status: <strong>{{paymentDetails?.status}}</strong><br/>
Now project_name and Status details will be displayed. Console gets "ERROR TypeError: Cannot read property 'project_name' of undefined"
If I added "?" like
{{paymentDetails?.project_name}}
No Details displayed. But console not having any Error.
This same coding method works well in Angular 5/6.
Any special method for Angular 8 ???
MY console output in TS file is
{
project_name: "test",
status: "true"
}
Previous question is How to Display Values in Angular 8 Shows ERROR TypeError: Cannot read property 'project_name' of undefined
but solution not working
anyone know how to resolve ?
Everything seems good, check if your component doesn't have
changeDetection: ChangeDetectiongStrategy.OnPush
If so, remove it and put back the '?' in the html markup, and then add it back and do the change detection in the subscribe

bind dynamically to this vuejs

Hey guys I have the following function its working ok but I think it could be better.
methods: {
onFileChange(e, filedName) {
console.log(e.target.files);
console.log(filedName);
const file = e.target.files[0];
const fileToCheck=document.getElementById(filedName);
console.log(fileToCheck);
if(filedName=='thumbnail1'){
if(fileToCheck.value!=''){
this.thumbnail1 = fileToCheck;
this.thumbnail1Url= URL.createObjectURL(file);
} else {
this.thumbnail1=null;
this.thumbnail1Url=null;
}
}
if(filedName=='thumbnail2'){
if(fileToCheck.value!=''){
console.log(fileToCheck);
this.thumbnail2=fileToCheck;
this.thumbnail2Url = URL.createObjectURL(file);
} else {this.thumbnail2=fileToCheck; this.thumbnail2Url=null;}
}
},
Instead of checking the value for
if(fieldName == "something"){
this.something = URL.createObjectURL(file)
}
I would simply pass in a string of the fieldName and bind to it dynamically by just typing this.fieldName (filedName could equal thumbnail1 or thumbnail2 or chicken for all I care I just want to be able to pass in the name of the data atrribute and bind to it that way) but when ever I do this it doesn't work. Any help here would be great.
It's not completely clear to me what you want to accomplish, but I think you're asking about creating a dynamic data property for a view component. If that's the case, there are a couple of things to consider.
First, the example you cite, this.fieldName is not correct JavaScript syntax if fieldName is a string that contains a property name. The correct version is this[fieldName].
Note, though, that you can't simply define a new data property for a Vue component by setting it to a value. That's a limitation of JavaScript that's described in the Vue documentation. If data[fieldName] is an existing property that's defined in the component's data object, then you'll be okay. Even if you don't know the value of the property, you can initialize it, for example, with a value of null and then update the value in your method. Otherwise, you'll need to add the property to an existing non-root-level property as the documentation explains.