WeChat Miniprogram send object from ts to wxs file - wechat

I am creating a WeChat miniprogram using typescript, I have a Person type class with the following data:
export class Person {
dob: Date;
firstName: String;
lastName: String;
}
Create Person object:
let person = new Person ();
person.dob = new Date ();
person.fisrtName = "XXX";
person.lastName = "YYY";
this.setData ({
person: person
})
At the time of displaying it in the wxml I am doing the following:
<view> {{person.firstName}} </view>
<view> {{person.lastName}} </view>
<view> {{person.dob}} </view>
The dob property shows it as [object Object]
I have created a method in a wxs file to transform the dob property and display it as a string by calling the toDateString method of the Date object, but it gives me the following error:
dob.toDateString() is not a function, if I call this method from the .ts file it works fine but when I call it from the wxs file it gives an error.

The javascript environment and wxs environment of view is divided.I guess you may try to require the wxs file in wxml like this:

Related

References a sub model from parent in typescript using prisma client

I am learning prisma and I can't figure out how to use the prisma types correctly if the returned data includes a sub model.
For example, I have the following two tables
model Services {
id Int #id #default(autoincrement())
service_name String #db.VarChar(255)
description String #db.MediumText
overall_status ServiceStatus #default(OPERATIONAL)
deleted Boolean #default(false)
sub_services SubServices[]
}
model SubServices {
id Int #id #default(autoincrement())
name String #db.VarChar(255)
description String #db.MediumText
current_status ServiceStatus #default(OPERATIONAL)
service Services? #relation(fields: [service_id], references: [id], onDelete: Cascade)
service_id Int?
}
I am then pulling data from the Services model using the following:
const services = await prisma.services.findMany({
where: {
deleted: false
},
include: {
sub_services: true
}
});
I am then in the client side referencing the Services model, but the IDE isn't detecting that Services can include sub_services. I can use it and it works but the IDE is always showing a squiggly line as if the code is wrong, example is below:
import {Services} from "#prisma/client";
const MyComponent : React.FC<{service: Services}> = ({services}) => {
return (
<>
service.sub_services.map(service => {
})
</>
)
}
but in the above example sub_services is underlined with the error TS2339: Property 'sub_services' does not exist on type 'Services'.
So how would I type it in a way that IDE can see that I can access sub_services from within services model.
UPDATE
I found a way to do it, but I'm not sure if this is the correct way or not as I am creating a new type as below:
type ServiceWithSubServices <Services> = Partial<Services> & {
sub_services: SubServices[]
}
and then change the const definition to the below
const ServiceParent : React.FC<{service: ServiceWithSubServices<Services>}> = ({service}) => {
Although this does seem to work, is this the right way to do it, or is there some more prisma specific that can do it without creating a new type.
In Prisma, by default only the scalar fields are included in the generated type. So, in your case for the Services type, all the scalar fields except sub_services would be included in the type. sub_services is not included because it's a relation field.
To include the relation fields, you would need to use Prisma.validator, here's a guide on generating types that include the relation field.

How to explicitly skip checking part of the schema in zod

I would like to understand if and how it is possible to skip validating parts of a schema in zod?
In the following example, I would like to validate the foo schema to make sure that the object contains a property id of type number and a property data of type array but (maybe cause there is a lot of data) I would like to prevent validating all the actual array entries in data.
import {z} from 'zod';
const foo = z.object({
id: z.number(),
data: z.array(z.string()),
});
This does the job:
const dataItem = z.custom<DataItem>(); // type DataItem defined by you elsewhere
const foo = z.object({
id: z.number(),
data: z.array(dataItem),
});
// { id: string; data: DataItem[] }
https://github.com/colinhacks/zod/discussions/1575

How do I merge slices of state for my presentational component properly (ngrx/store)?

I'm still trying to learn ngrx - the store is set-up and everything seems to work fine. The database I'm using is SQL so basically I'm "clongin" the tables and load them into the store but have problems joining the state in the end when selecting an employee.
The employee entity looks something like this:
export class Employee = {
id: number;
firstName: string;
lastName: string;
degreeId?: number;
degree: Degree;
}
export class Degree = {
id: number;
description: string;
}
Now in my component, I'd like to get the specific employee to display like this:
{
id: 1,
firstName: George,
lastName: Costanza,
degreeId: 2,
degree: {
id: 2,
description: 'College'
}
}
What I tried is to create a selector that merges these two entities:
export const getEmployeeWithAllData = createSelector(
getSelectedEmployee,
getRelationalData,
(employee, data) => {
const employeesDegree = degree[employee.degreeId]
employee.degree = employeesDegree
return employee;
}
);
This does seem to work if I don't use ngrx-store-freeze - so since I don't know if I am creating the selector correctly or if ngrx-store-freeze has a bug I'm asking this question.
Am I really mutating state when I do this?
If yes, how can I select a specific employee from my store with all the relational data that he has?
What I'm doing doesn't really feel right. In my actual application the employee has about 8 fields of relational data which I need to join...
Edit: I forgot to include the error ngrx-store-freeze throws:
ERROR TypeError: Cannot assign to read only property 'degree' of object '[object Object]'
at eval (employee.selector.ts:85)
at eval (store.es5.js:602)
at memoized (store.es5.js:539)
at defaultStateFn (store.es5.js:573)
at eval (store.es5.js:605)
at MapSubscriber.memoized [as project] (store.es5.js:539)
at MapSubscriber._next (map.js:79)
at MapSubscriber.Subscriber.next (Subscriber.js:95)
at MapSubscriber._next (map.js:85)
at MapSubscriber.Subscriber.next (Subscriber.js:95)
yes, you are trying to mutate the state. You can prevent this simply like bellow
export const getEmployeeWithAllData = createSelector(
getSelectedEmployee,
getRelationalData,
(employee, data) => {
const emp = JSON.parse(JSON.stringify(employee)
emp.degree = degree[employee.degreeId]
return emp;
}
)

How do you clear an immutable.js map back to its defaults

I have an immutable.js map. For example:
// default, when user first gets on page
var myObject = Immutable.Map({
productID: '',
colors: ['brown', 'red'],
sku: ''
sizes: [10]
})
Now, depending on how they get to my app - I populate that above "myObject" with different data.
so, for example: lets say they come from pathA
// pathA passes in some data... hydrate the myObject
var myObject = Immutable.Map({
productID: '090ABl',
colors: ['brown', 'red', 'yellow'],
sku: '__whatever'
sizes: [10, 18, 9]
})
so, for example: lets say they come from pathB
** this is where the issue comes from. I have that previous "state" of myObject hanging around. I need to "clear and go back to the initial state". I am using redux.
// pathB passes in some data... hydrate the myObject
var myObject = Immutable.Map({
productID: '090XZLG',
colors: ['red', 'yellow'],
sku: '__food'
sizes: [9]
})
The data is combing etc.. I need it to "clear out.". Curious if there is an Immutable.js method that enables to refresh the myObject with a new one, that is the same as the initial state. I am new to immutable.js so I am a bit curious about why its so hard to do simple things :-)
When using immutable for the state object in redux, in many of my reducers I set a certain key to what I get from the initial state.
i.e.:
function reeducer(state = initialState, action) {
switch (action.type) {
...
case CLEAR_SELECTION:
return state.set('selected', initialState.get('selected'));
...
}
}
And of course to make it a bit cleaner (specially to avoid repeating a string) one could create a function for this:
function resetKey(state, initialState, key) {
return state.set(key, initialState.get(key));
}
(Alternatively it could be called copyKey or copySection)
Or it could be a resetPath/copyPath
function resetPath(state, initialState, path) {
return state.setIn(key, initialState.getIn(path));
}
The immutable.js object does not 'know' what its 'defaults' are, so there is no way of resetting it. If you have a default object in your application just keep a reference to that in a variable, like you would if it were a plain JavaScript object:
var defaultObject = Immutable.Map({
productID: '',
colors: ['brown', 'red'],
sku: ''
sizes: [10]
})
Then when the user arrives at a certain path, you simply make your modifications and keep them in a different variable:
var myObject = defaultObject.set(...);

Is there a way to update the URL in Flow Router without a refresh/redirect?

Is there a way to update a part of the URL reactively without using FlowRouter.go() while using React and react-layout?
I want to change the value in the document that is used to get the document from the DB. For example, if I have a route like ~/users/:username and update the username field in the document, I then have to user FlowRouter.go('profile', {data}) to direct the user to that new URL. The "old" route is gone.
Below is the working version I have, but there are two issues:
I have to use FlowRouter.go(), which is actually a full page refresh (and going back would be a 404).
I still get errors in the console because for a brief moment the reactive data for the component is actually wrong.
Relevant parts of the component are like this:
...
mixins: [ReactMeteorData],
getMeteorData() {
let data = {};
let users = Meteor.subscribe('user', {this.props.username});
if (user.ready())
data.user = user;
return data;
}
...
updateName(username) {
Users.update({_id:this.data.user._id}, {$set:{username}}, null, (e,r) => {
if (!e)
FlowRouter.go('profile', {username});
});
},
...
The route is like this:
FlowRouter.route('/users/:username', {
name: 'profile',
action(params) {
ReactLayout.render(Main, {content: <UserProfile {...params} />});
}
});
The errors I get in the console are:
Exception from Tracker recompute function:
and
TypeError: Cannot read property '_id' of undefined

Resources