Vuex store changes not reactive in components - vue.js

I have a basic store for inserting and deleting from an array
state: {
assessmentTypes : []
},
mutations: {
setAssessmentTypes(state, assessmentTypes) {
assessmentTypes.forEach(assessmentType => {
state.assessmentTypes.push(assessmentType);
});
},
removeAssessmentType ( state, assessmentTypeId ) {
let assessmentTypeIndex = state.assessmentTypes.map(assessmentType => assessmentType.id).indexOf(assessmentTypeId);
state.assessmentTypes.splice(assessmentTypeIndex, 1)
}
}
I get the state assessmentTypes in computed property in one of my components.
computed:{
assessmentTypes : {
get () {
return this.$store.state.assessmentTypes;
}
}
The problem is I am looping the array in dom for listing a div, but the computed property is not reactive. When I delete or insert a new object into/from the array (through actions), the dom is not rerendering.
Object structure
{
"id": "T7pLDdjmFWAqGiuqB",
"name": "bbb",
"code": "BBB",
"properties": {
combinationOfAssessments: false,
staffCanCreateInstance: false
},
"identifyingContext": {
"semId": "2",
"batchId": "54",
"staffId": "155",
"subjectId": "966",
"subbatchId": "391"
},
"permissions": {
"hod": "1",
"staff": "1"
},
"isActive": "1",
"createdBy": null,
"createdUserName": null,
"createdByUserType": null,
"createdDate": null,
"updatedDate": null,
"updatedBy": null,
"updatedUserName": null,
"updatedByUserType": null,
"propertiesValue": null
}

Related

Nest JS - Serialization not work with nested object

I want to append a new field called logo_img_url after data manipulation. It works with the object but the nested array object seems not to work. Any recommendations or solution
import { Expose } from 'class-transformer';
import {} from 'class-validator';
import { Entity, Column } from 'typeorm';
import { BaseEntity } from '#common/base/entity.base';
import { getAdminImageUrl } from '#common/util/vault-file.util';
#Entity()
export class Agency extends BaseEntity {
#Expose()
#Column({
type: 'varchar',
length: '255',
nullable: true,
})
public logo_key!: string;
#Expose({ name: 'logoImgUrl' })
logo_img_url = this.logoImgUrl;
#Expose()
get logoImgUrl(): any {
return "http://localhost:30001/". this.logo_key;
}
}
Actaul response:
{
"data": [
{
"logo_img_url": "",
"id": 22,
"logo_url": "9597e74d-aaea-4502-b5cd-b2867504fd80",
},
{
"logo_img_url": "",
"id": 21,
"logo_url": "0a655497-1318-4276-a21f-cfdc259241a2",
},
],
"meta": {
"status_code": 200,
"pagination": {
"totalPages": 1,
"currentPage": 1,
"nextPage": null,
"paginationToken": null,
"previousPage": null,
"totalItems": 9,
"itemsPerPage": 10
}
}
}
Expected result:
{
"data": [
{
"logo_img_url": "http://localhost:3000/9597e74d-aaea-4502-b5cd-b2867504fd80",
"id": 22,
"logo_url": "9597e74d-aaea-4502-b5cd-b2867504fd80",
},
{
"logo_img_url": "http://localhost:3000/0a655497-1318-4276-a21f-cfdc259241a2",
"id": 21,
"logo_url": "0a655497-1318-4276-a21f-cfdc259241a2",
},
],
"meta": {
"status_code": 200,
"pagination": {
"totalPages": 1,
"currentPage": 1,
"nextPage": null,
"paginationToken": null,
"previousPage": null,
"totalItems": 9,
"itemsPerPage": 10
}
}
}
You can use #AfterLoad decorator from typeorm. Its calls the decorated method once the entity is loaded and then one can perform the required manipulations.
logo_img_url:string
#AfterLoad()
async transform(){
this.logo_img_url=`http://localhost:30001/${this.logo_key}`
}

Filter the JSON object where value is not empty or not null on created function on vue.js 3

I want to get the response.data (JSON Object) with value only in the new object on update form i.e. I want to filter it on computed/created on vue 3 - the json object received from API. My backend is Laravel 8 resource API.
On EditPatient.vue - The vue js is
export default {
data() {
return {
patient: {},
}
},
created() {
this.$axios.get('/sanctum/csrf-cookie').then(response => {
this.$axios.get(`/api/patients/${this.$route.params.id}`)
.then(response => {
this.patient = response.data // JSON object
/* .filter(function(item) {
item !== null || item !=='';
}) */ // this didn't work.
//I want to response.data and apply to this.patient object.
})
.catch(function (error) {
console.error(error);
});
})
},
}
response.data is
{ "created_by": 1, "firstname": "Kamal", "lastname": "", "sex": "M", "address": "Kathmandu, Bagmati, Nepal", "education": "Yes", "grade": "MSc", "alcohol": null, "alcohol_type": null, "weight": "", "kidney_disease": null, "high_bp": "No", "diabetes": null, "heart_attack_stroke": "No", "present_diabetes": "No", "systolic": "", "pulse_rate": "" }
On laravel api, I got a patient row as follow:
public function show($id)
{
$patient = Patient::find($id);
return response()->json($patient); // send data in json ojbect for frontend
}
It is better, If I can apply on backend too. Get the columns of single row which has value only.
To get only the object properties that are not empty/null:
Use Object.entries() on the response.data object to get an array of key/value pairs.
Use Array.prototype.filter() on the result, filtering out empty string and null.
Use Object.fromEntries() on the filtered result to create an object.
const input = { "created_by": 1, "firstname": "Kamal", "lastname": "", "sex": "M", "address": "Kathmandu, Bagmati, Nepal", "education": "Yes", "grade": "MSc", "alcohol": null, "alcohol_type": null, "weight": "", "kidney_disease": null, "high_bp": "No", "diabetes": null, "heart_attack_stroke": "No", "present_diabetes": "No", "systolic": "", "pulse_rate": "" }
const entries = Object.entries(input) // 1️⃣
const nonEmptyOrNull = entries.filter(([key,val]) => val !== '' && val !== null) // 2️⃣
const output = Object.fromEntries(nonEmptyOrNull) // 3️⃣
console.log(output)

Unable to loop through data from SQLite call in React Native, Expo

I'm currently making a call to an SQLite local database in my react native
Expo app like so:
db.transaction(tx => {
tx.executeSql('select * from dr_report_templates', [], (_, { rows }) => {
const templateData = JSON.stringify(rows);
this.setState({ options: templateData, isLoading: false }, () => console.log(this.state))
});
},
error => {
alert(error);
},
() => console.log('Loaded template settings')
);
I'm returning the data and making it a JSON string with: JSON.stringify
Data appears like so:
Object {
"isLoading": false,
"options": "{\"_array\":[{\"id\":30,\"name\":\"SFR General\",\"description\":\"SFR1\"},{\"id\":31,\"name\":\"SFR Extended\",\"description\":\"SFR2\"},{\"id\":7790,\"name\":\"test_new_template\",\"description\":\"test_new_template\"},{\"id\":7792,\"name\":\"apart_1\",\"description\":\"apart_1\"},{\"id\":7793,\"name\":\"SFR\",\"description\":\"Single Family\"},{\"id\":7798,\"name\":\"Condo\",\"description\":\"Condo \"},{\"id\":7799,\"name\":\"Duplex\",\"description\":\"Duplex\"},{\"id\":7800,\"name\":\"Triplex \",\"description\":\"3\"},{\"id\":7801,\"name\":\"Apartments\",\"description\":\"Apartment complex\"},{\"id\":7802,\"name\":\"Commercial retail store \",\"description\":\"Storefront \"},{\"id\":7803,\"name\":\"5-10 unit\",\"description\":\"5\"},{\"id\":7804,\"name\":\"Commercial Industrial \",\"description\":\"Industrial \"},{\"id\":7805,\"name\":\"Industrial Property\",\"description\":\"RE\"}],\"length\":13}",
"selected": "",
}
Attempting to get values for just the first array element like so:
this.state.options[0]
does not work. I'm obviously doing something wrong in the way that I'm doing this but can't figure out what. Any ideas?
EDIT: I had also ran the query with out JSON.Stringify. The data returned like so with this "t" in front of it. I've never hard this before and I couldn't loop through it so that's why I did a JSON.stringify.
t {
"_array": Array [
Object {
"description": "SFR1",
"id": 30,
"name": "SFR General",
},
Object {
"description": "SFR2",
"id": 31,
"name": "SFR Extended",
},
Object {
"description": "test_new_template",
"id": 7790,
"name": "test_new_template",
},
Object {
"description": "apart_1",
"id": 7792,
"name": "apart_1",
},
Object {
"description": "Single Family",
"id": 7793,
"name": "SFR",
},
Object {
"description": "Condo ",
"id": 7798,
"name": "Condo",
},
Object {
"description": "Duplex",
"id": 7799,
"name": "Duplex",
},
Object {
"description": "3",
"id": 7800,
"name": "Triplex ",
},
Object {
"description": "Apartment complex",
"id": 7801,
"name": "Apartments",
},
Object {
"description": "Storefront ",
"id": 7802,
"name": "Commercial retail store ",
},
Object {
"description": "5",
"id": 7803,
"name": "5-10 unit",
},
Object {
"description": "Industrial ",
"id": 7804,
"name": "Commercial Industrial ",
},
Object {
"description": "RE",
"id": 7805,
"name": "Industrial Property",
},
],
"length": 13,
}
this.setState({ options: templateData._array, isLoading: false });
or change how you destructure in 3rd parameter of executeSql to:
(_, { rows: { _array } }) => {
const templateData = JSON.stringify(_array);
}
Why you're conveting it with JSON.stringify()? You can iterate over array or access it with array's key name.
NOTE: JSON.stringify() does not convert it to JSON. It converts to JSON string
The JSON.stringify() method converts a JavaScript object or value to a
JSON string, optionally replacing values if a replacer function is
specified or optionally including only the specified properties if a
replacer array is specified.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
You're actually converting your database response to string.
So Change
const templateData = JSON.stringify(rows);
to
const templateData = rows;
and use this array where you want.

Using Stripe webhooks with graphql-yoga and Prisma

I'm having some trouble finding how to intercept Stripe webhook calls in my application. I use graphql-yoga (express) and prisma.
I have to listen to payment failure calls from Stripe so I can edit the corresponding user profile.
Thanks for the help!
Stripe webhook calls look like so :
{
"created": 1326853478,
"id": "charge.expired_00000000000000",
"type": "charge.expired",
"object": "event",
"request": null,
"pending_webhooks": 1,
"data": {
"object": {
"id": "ch_00000000000000",
"object": "charge",
"amount": 100,
"captured": false,
"created": 1537153592,
"currency": "usd",
"customer": null,
"description": "My First Test Charge (created for API docs)",
"invoice": null,
"livemode": false,
"on_behalf_of": null,
"order": null,
"outcome": null,
"paid": true,
"receipt_email": null,
"receipt_number": null,
"refunded": false,
"review": null,
"shipping": null,
"source": {
"id": "card_00000000000000",
"object": "card",
"address_city": null,
"address_country": null,
"address_line1": null,
"address_line1_check": null,
"address_line2": null,
"address_state": null,
"address_zip": "12919",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_00000000000000",
"cvc_check": null,
"name": null,
"tokenization_method": null
},
"statement_descriptor": null,
"status": "succeeded",
}
}
}
Since Stripe Webhook returns a generic http POST with JSON payload, it will not format the event data according to Graphql language query.
For now, what you can do is to expose a normal REST API endpoint using Graphql-Yoga's express[0]
I have composed a working sample code you can try it out
const { GraphQLServer } = require('graphql-yoga')
const typeDefs = `
type Query {
hello(name: String): String!
}
`
const resolvers = {
Query: {
hello: (_, { name }) => `Hello ${name || 'World'}`,
},
}
const server = new GraphQLServer({ typeDefs, resolvers, skipValidation: true })
server.express.use('/api/stripe/webhooks', (req, res) => {
// Handle your callback here !!!!
res.status(200).send();
})
server.start(() => console.log('Server is running on localhost:4000'))
Let me know if the above helps.
[0] https://github.com/prisma/graphql-yoga#how-to-eject-from-the-standard-express-setup

Lodash: Group and restructure the json object using Lodash

How can i group and restructure the json object using lodash.
Have a json object like this
var data = [
{
"Type": "W",
"Id": 1,
"Employee_Role_Desc": null,
"Employee_Role_Id": 1,
"StartDateTime": "2017-06-15T09:00:00",
"EndDateTime": "2017-06-15T12:30:00",
"Alert": null
},
{
"Type": "W",
"Id": 1,
"Employee_Role_Desc": null,
"Employee_Role_Id": 1,
"StartDateTime": "2017-06-15T09:00:00",
"EndDateTime": "2017-06-15T12:30:00",
"Alert": null
}, {
"Type": "W",
"Id": 1,
"Employee_Role_Desc": null,
"Employee_Role_Id": 3,
"StartDateTime": "2017-06-15T09:00:00",
"EndDateTime": "2017-06-15T12:30:00",
"Alert": null
}
]
Want to group t like this.
{
"Role_Id": 1,
"Date": "2017-06-15T05:12:22.9577063-05:00",
"**Blocks**": [
{
"StartDateTime": "2017-06-15T05:12:22.9586499-05:00",
"EndDateTime": "2017-06-15T05:12:22.9586499-05:00"
},
{
"StartDateTime": "2017-06-15T05:12:22.9586499-05:00",
"EndDateTime": "2017-06-15T05:12:22.9586499-05:00"
}
]
}
Group it by Employee_Role_Id and each StartDateTime and EndDateTime should be in a Blocks object
"Role_Id" in the result should be the "Employee_Role_Id" in resultant object.
You can achieve that using _.groupBy(), and _.map() in a chain:
const data = [{"Type":"W","Id":1,"Employee_Role_Desc":null,"Employee_Role_Id":1,"StartDateTime":"2017-06-15T09:00:00","EndDateTime":"2017-06-15T12:30:00","Alert":null},{"Type":"W","Id":1,"Employee_Role_Desc":null,"Employee_Role_Id":1,"StartDateTime":"2017-06-15T09:00:00","EndDateTime":"2017-06-15T12:30:00","Alert":null},{"Type":"W","Id":1,"Employee_Role_Desc":null,"Employee_Role_Id":3,"StartDateTime":"2017-06-15T09:00:00","EndDateTime":"2017-06-15T12:30:00","Alert":null}];
const result = _(data)
.groupBy('Employee_Role_Id') // group the items
.map((group, Role_Id) => ({ // map the groups to new objects
Role_Id,
Date: group[0].StartDateTime,
Blocks: group.map(({ StartDateTime, EndDateTime }) => ({ // extract the dates from the groups
StartDateTime,
EndDateTime
}))
}))
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>