i'm working on a nuxt 3 project.
i've created a composable useAvailabilityRoom.ts but suddendy, it stopped working to throw this error :
Error: nuxt instance unavailable 10:42:04
at Module.useNuxtApp (/Users/chilperic/Sites/cabinetpartage/node_modules/nuxt/dist/app/nuxt.mjs:165:13)
at Module.useAsyncData (/Users/chilperic/Sites/cabinetpartage/node_modules/nuxt/dist/app/composables/asyncData.mjs:24:38)
at Module.useFetch (/Users/chilperic/Sites/cabinetpartage/node_modules/nuxt/dist/app/composables/fetch.mjs:52:43)
at Module.__vite_ssr_exports__.default (/Users/chilperic/Sites/cabinetpartage/composables/useUsers.ts:6:55)
at Module.__vite_ssr_exports__.default (/Users/chilperic/Sites/cabinetpartage/composables/useRoomAvailability.ts:61:55)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async setup (/Users/chilperic/Sites/cabinetpartage/pages/salles/[idLocation]/[idRoom].vue:59:12)
my call in page component
try {
const roomAvailability = await useRoomAvailability(route.params.idRoom);
} catch (e) {
console.log(e);
}
my composable code
class RoomSchedule {
roomId: String = "";
days = [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
];
monday = [];
tuesday = [];
wednesday = [];
thursday = [];
friday = [];
saturday = [];
sunday = [];
constructor(roomId: String) {
this.roomId = roomId;
}
checkAvailability(profile) {
for (let d in this.days) {
if (
profile.weekly_schedule[this.days[d]] !== false &&
profile.weekly_schedule[this.days[d]][this.roomId] !==
undefined &&
profile.weekly_schedule[this.days[d]][this.roomId] == true
) {
// on crée un objet de rendez-vous
const apt = {
begins_at: "07:00",
ends_at: "20:00",
name: profile.first_name + " " + profile.last_name,
job: profile.job,
user: profile.user_id,
};
// on compare les deux objets pour ne pas insérer un doublon
if (
this[this.days[d]].find(
(element) =>
JSON.stringify(element) === JSON.stringify(apt)
) == undefined
) {
this[this.days[d]].push({
begins_at: "07:00",
ends_at: "20:00",
name: profile.first_name + " " + profile.last_name,
job: profile.job,
user: profile.user_id,
});
}
} else {
// console.log("rien pour " + this.days[d]);
}
}
return true;
}
}
export default async (roomId: String) => {
// récupérer la dispo de la salle
const locationsObject = await useLocations();
const locations = Object.values({ ...locationsObject });
const room = locations.filter((el) => el.identifier == roomId);
const roomAvailability = toRaw(room[0]).availability;
let Schedule = new RoomSchedule(roomId);
// récupérer les résa des thérapeutes en bail
const profiles = await useUsers();
for (let av in profiles) {
// on parcourt les jours et on regarde s'il y a des thérapeutes au bail
for (let day in profiles[av].weekly_schedule) {
await Schedule.checkAvailability(profiles[av]);
}
}
return Schedule;
};
If i log the checkAvailability content, i have the right data.
I don't understand how to fix this error. Hope you can see what's wrong.
Related
I got an error when I try to get Time set data from Cloud Firestore.
I think if I set timestampsInSnapshots: true then the issue will be fixed, but I can't set it because I use cloud_firestore: ^0.16.0 so I couldn't found how can I do this. if I use cloud_firestore: ^0.8.2+1 then I can configure the Firestore's settings. But I wanna set this configuration in version 0.16.0
About Issue:
The following _TypeError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#ec8a0):
type 'Timestamp' is not a subtype of type 'int'
The relevant error-causing widget was
StreamBuilder<QuerySnapshot>
lib/…/main/profile.dart:66
When the exception was thrown, this was the stack
#0 _ProfileState.buildExamHistoryList.<anonymous closure>.<anonymous closure>
lib/…/main/profile.dart:97
#1 MappedListIterable.elementAt (dart:_internal/iterable.dart:411:31)
#2 ListIterator.moveNext (dart:_internal/iterable.dart:340:26)
#3 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:188:27)
#4 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
...
enter image description here
The stream where I wanna set my data from firestore:
Widget buildExamHistoryList() {
return StreamBuilder<QuerySnapshot>(
stream: usersRef.doc(widget.userID).collection('examResults').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Center(
child: Text("Something Went Wrong"),
);
}
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Container(
padding: EdgeInsets.only(top: 100),
child: Center(
child: SpinKitFadingCircle(
color: Colors.black,
size: 50,
),
),
);
break;
default:
return Column(
children: [
ListView(
shrinkWrap: true,
children: snapshot.data.docs.map((doc) {
return Padding(
padding: const EdgeInsets.all(10),
child: ExamHistoryCard(
correctAnswersCount: doc['correctAnswersCount'],
incorrectAnswersCount: doc['incorrectAnswersCount'],
date: _examHistoryService.readTimestamp(doc['date']),
),
);
}).toList(),
),
],
);
}
},
);
}
and that is my readTimestamp function:
String readTimestamp(int timestamp) {
var now = DateTime.now();
var format = DateFormat('HH:mm a');
var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
var diff = now.difference(date);
var time = '';
if (diff.inSeconds <= 0 ||
diff.inSeconds > 0 && diff.inMinutes == 0 ||
diff.inMinutes > 0 && diff.inHours == 0 ||
diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date);
} else if (diff.inDays > 0 && diff.inDays < 7) {
if (diff.inDays == 1) {
time = diff.inDays.toString() + ' Dünen';
} else {
time = diff.inDays.toString() + ' Gün Önce';
}
} else {
if (diff.inDays == 7) {
time = (diff.inDays / 7).floor().toString() + ' Hefte Önce';
} else {
time = (diff.inDays / 7).floor().toString() + ' Hefte Önce';
}
}
return time;
}
The dates you get from firebase in doc['date'] is a Timestamp, not an int. You can transform it into a Date by using toDate() method or to milliseconds since epoch with toMillis() like this:
final Timestamp timestamp = doc['date'];
final DateTime date = timestamp.toDate();
final int millis = timestamp.toMillis()
Also be sure to declare the correct type you are going to be passing to your readTimestamp function:
String readTimestamp(Timestamp timestamp) {}
or
String readTimestamp(DateTime date) {}
or
String readTimestamp(int millis) {}
Try this
String readTimestamp(Timestamp timestamp) {
var now = DateTime.now();
var format = DateFormat('HH:mm a');
var date = timestamp.toDate();
var diff = now.difference(date);
var time = '';
if (diff.inSeconds <= 0 ||
diff.inSeconds > 0 && diff.inMinutes == 0 ||
diff.inMinutes > 0 && diff.inHours == 0 ||
diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date);
} else if (diff.inDays > 0 && diff.inDays < 7) {
if (diff.inDays == 1) {
time = diff.inDays.toString() + ' Dünen';
} else {
time = diff.inDays.toString() + ' Gün Önce';
}
} else {
if (diff.inDays == 7) {
time = (diff.inDays / 7).floor().toString() + ' Hefte Önce';
} else {
time = (diff.inDays / 7).floor().toString() + ' Hefte Önce';
}
}
return time;
}
Timestamp from Firebase will be formatted as Timestamp or Map.
Here DatetimeConverter taking care of the conversion from/to json from Firebase Firestore and Cloud Functions:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
class DatetimeConverter implements JsonConverter<DateTime, dynamic> {
const DatetimeConverter();
#override
dynamic toJson(DateTime object) {
return object != null
? Timestamp.fromDate(object)
: FieldValue.serverTimestamp();
}
#override
DateTime fromJson(dynamic val) {
Timestamp timestamp;
if (val is Timestamp) {
// the firestore SDK formats the timestamp as a timestamp
timestamp = val;
} else if (val is Map) {
// cloud functions formate the timestamp as a map
timestamp = Timestamp(val['_seconds'] as int, val['_nanoseconds'] as int);
}
if (timestamp != null) {
return timestamp.toDate();
} else {
// Timestamp probably not yet written server side
return Timestamp.now().toDate();
}
}
}
How can I arrange the date in the proper format?
On the screen the date wrong, it shows 32/03/2020 but day 32 does not exist.
The correct format date is on the image below.
I am new with Reactjs, what has gone wrong in my code and how can I solve it?
My code is below:
class Chamado extends Component {
constructor(props) {
super(props);
this.state = {
offset: 0,
pageCount: this.props.chamados.length / this.props.perPage,
};
this.formatDate = this.formatDate.bind(this);
this.handlePageClick = this.handlePageClick.bind(this);
}
formatDate(date) {
const dateObject = new Date(date);
const day =
dateObject.getDate() + 1 < 10
? '0' + (dateObject.getDate() + 1)
: dateObject.getDate() + 1;
const month =
dateObject.getMonth() + 1 < 10
? '0' + (dateObject.getMonth() + 1)
: dateObject.getMonth() + 1;
const year = dateObject.getFullYear();
const formattedString = `${day}/${month}/${year}`;
return formattedString;
}
handlePageClick(data) {
let selected = data.selected;
let offset = Math.ceil(selected * this.props.perPage);
this.setState({
offset: offset,
});
}
render() {
const props = this.props;
return (
<SC.Container>
<SC.Title>
Histórico de <b>Chamados</b>
{this.props.chamados.length !== undefined && (
<SC.Add
title="Abrir um novo chamado"
onClick={(event) => props.setViewAbrirChamados(true)}
>
<GoPlus size="21px" color="#FFF" />
</SC.Add>
)}
</SC.Title>
<SC.List>
{this.props.chamados.length !== undefined ? (
<React.Fragment>
{props.chamados.length > 0 &&
props.chamados.map((item, index) => {
const maxOffset = this.state.offset + (props.perPage - 1);
return (
index >= this.state.offset &&
index <= maxOffset && (
<SC.Item key={item.id}>
<SC.Info>
<SC.Details>
<p>
<b>
{item.id} |{' '}
{item.titulo || item.categoria.descricao}
</b>
</p>
<p>
{this.formatDate(item.data_abertura)} -{' '}
{item.hora_abertura}
</p>
</SC.Details>
</SC.Info>
<SC.Buttons
onClick={(event) => {
props.setViewChamadoInfo(true, item.id);
}}
>
<button>
<FaInfo size="24" color="#fff" />
</button>
</SC.Buttons>
</SC.Item>
)
The format is on the image below:
What you need is a padding function something like below
const padNumber = (number) => {
if (number.toString().length === 1) return `0${number}`;
return number;
};
const formatDate = (date) => {
const dateObject = new Date(date);
const day = dateObject.getDate();
const month = dateObject.getMonth() + 1;
const year = dateObject.getFullYear();
const formattedString = `${padNumber(day)}/${padNumber(month)}/${year}`;
return formattedString;
};
Still the easiest way would be using moment.js
I'm trying to save only 2 items when persisting through redux-persist .
I'm perplexed why the following code won't work..
(it seems to save more than 2 items)
const myTransform = createTransform(
(inboundState, key) => {
let { openforum_threads } = inboundState
if (!openforum_threads) {
return inboundState
}
let { allIds } = openforum_threads
let STORE_NUM = 2
let storeIds = allIds.slice(0, STORE_NUM)
console.log('saving', storeIds)
let { byId } = openforum_threads
let storeById = {}
storeIds.map((id) => {
storeById[id] = byId[id]
})
openforum_threads = {
...openforum_threads,
allIds: storeIds,
byId: storeById
}
return { ...inboundState, openforum_threads}
},
(outboundState, key) => {
// convert mySet to an Array.
return outboundState
}
)
I have 2 functions in Template.meetings.helpers, but only one function is working.
Template.meetings.helpers({
group: function() {
console.log('meeting id from helper group = ' + this.meetingId);
console.log('group id from helper group = ' + this.groupId);
return Groups.findOne({_id: this.groupId});
},
meeting: function() {
console.log('meeting id from helper meeting = ' + this.meetingId);
console.log('group id from helper meeting = ' + this.groupId);
return Meetings.findOne({_id: this.meetingId});
},
});
My console shows the following:
router.js:73 meetingId from router = ZKkLLvdCpRmrF7uXD
router.js:74 groupId from router = xFSzAHBEps2dSKcWM
meetings.js:26 meeting id from helper meeting = ZKkLLvdCpRmrF7uXD
meetings.js:27 group id from helper meeting = xFSzAHBEps2dSKcWM
router.js:
Router.route('/meetings/:_id/:groupId?', {
waitOn: function() {
return Meteor.subscribe('meeting');
return Meteor.subscribe('Group');
},
action: function () {
console.log('meetingId from router = ' + this.params._id);
console.log('groupId from router = ' + this.params.groupId);
this.render('meetings', {
data: {
meetingId: this.params._id,
groupId: this.params.groupId
}
});
},
onBeforeAction: function(){
var currentGroup = Members.find({
groupId: this.params.groupId,
memberId: Meteor.userId()
}).count();
Session.set('groupId', this.params.groupId);
var currentUser = Meteor.userId();
if(currentUser && currentGroup > 0){
this.next();
} else {
this.render("landingPage");
}
}
});
I can't figure out why the group: function() is not outputting to the console.
Any suggestions?
When I server-filter on "au" my web grid and change page, multiple call to the controller are done :
the first with 0 filtering,
the second with "a" filtering,
the third with "au" filtering.
My table load huge data so the first call is longer than others.
I see the grid displaying firstly the third call result, then the second, and finally the first call (this order correspond to the response time of my controller due to filter parameter)
Why are all that controller call made ?
Can't just my controller be called once with my total filter "au" ?
What should I do ?
Here is my grid :
$("#" + gridId).kendoGrid({
selectable: "row",
pageable: true,
filterable:true,
scrollable : true,
//scrollable: {
// virtual: true //false // Bug : Génère un affichage multiple...
//},
navigatable: true,
groupable: true,
sortable: {
mode: "multiple", // enables multi-column sorting
allowUnsort: true
},
dataSource: {
type: "json",
serverPaging: true,
serverSorting: true,
serverFiltering: true,
serverGrouping:false, // Ne fonctionne pas...
pageSize: '#ViewBag.Pagination',
transport: {
read: {
url: Procvalue + "/LOV",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8"
},
parameterMap: function (options, type) {
// Mise à jour du format d'envoi des paramètres
// pour qu'ils puissent être correctement interprétés côté serveur.
// Construction du paramètre sort :
if (options.sort != null) {
var sort = options.sort;
var sort2 = "";
for (i = 0; i < sort.length; i++) {
sort2 = sort2 + sort[i].field + '-' + sort[i].dir + '~';
}
options.sort = sort2;
}
if (options.group != null) {
var group = options.group;
var group2 = "";
for (i = 0; i < group.length; i++) {
group2 = group2 + group[i].field + '-' + group[i].dir + '~';
}
options.group = group2;
}
if (options.filter != null) {
var filter = options.filter.filters;
var filter2 = "";
for (i = 0; i < filter.length; i++) {
// Vérification si type colonne == string.
// Parcours des colonnes pour trouver celle qui a le même nom de champ.
var type = "";
for (j = 0 ; j < colonnes.length ; j++) {
if (colonnes[j].champ == filter[i].field) {
type = colonnes[j].type;
break;
}
}
if (filter2.length == 0) {
if (type == "string") { // Avec '' autour de la valeur.
filter2 = filter2 + filter[i].field + '~' + filter[i].operator + "~'" + filter[i].value + "'";
} else { // Sans '' autour de la valeur.
filter2 = filter2 + filter[i].field + '~' + filter[i].operator + "~" + filter[i].value;
}
} else {
if (type == "string") { // Avec '' autour de la valeur.
filter2 = filter2 + '~' + options.filter.logic + '~' + filter[i].field + '~' + filter[i].operator + "~'" + filter[i].value + "'";
}else{
filter2 = filter2 + '~' + options.filter.logic + '~' + filter[i].field + '~' + filter[i].operator + "~" + filter[i].value;
}
}
}
options.filter = filter2;
}
var json = JSON.stringify(options);
return json;
}
},
schema: {
data: function (data) {
return eval(data.data.Data);
},
total: function (data) {
return eval(data.data.Total);
}
},
filter: {
logic: "or",
filters:filtre(valeur)
}
},
columns: getColonnes(colonnes)
});
Here is my controller :
[HttpPost]
public ActionResult LOV([DataSourceRequest] DataSourceRequest request)
{
return Json(CProduitsManager.GetProduits().ToDataSourceResult(request));
}
The 3 correspond to the initial load (no filtering) and the following ones as you type in the condition of filter, similar in kendoAutocomplete but in kendoAutocomplete there are a couple of options (time and min length) that control when to send the requests (I couldn't find anything similar in grid).
If your problem is loading a huge amount of data I do recommend limiting the size of the data transmitted using pageSize in the DataSource definition. But, obviously, this is not a solution if what takes long is executing the query.
In such scenarios it is recommended to create a typing delay and thus perform a request when the user has stopped typing (unless he is typing slower than regular typing).
To create a delay I can suggest you the following:
<script type="text/javascript">
var globalTimeout = null;
$('#searchInput').keyup(function () {
if (globalTimeout != null) clearTimeout(globalTimeout);
globalTimeout = setTimeout(SearchFunc, 500);
});
function SearchFunc(){
globalTimeout = null;
$('#yourGridName').data('kendoGrid').dataSource.filter({ field:"theField",operator:"startswith",value:$('#searchInput').val() })
}
</script>