Our pure JavaScript Scheduler component


Post by omerkati »

It was sending this: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS

So what we are wondering is what our backend is supposed to expect. We were expecting that it will send a post request. I took a look at the php code from the example, but since we are not using php it is not very useful. If it is only possible in php then we might need to look for other options.


Post by Maxim Gorkovsky »

Crud manager should not send OPTIONS request. Load uses GET, sync uses POST. Could you please post complete config of your scheduler/crud manager?


Post by omerkati »

const schedulerConfig = {
    flex: '1 1 50%',
    tree: true,
    resourceStore: {
        transformFlatData: true,
        tree: true
    },
    eventDragFeature: {
        constrainDragToResource: true
    },

crudManager: {
    autoSync: true,
    autoLoad: true,
    transport: {
        // load: {
        //     url: 'data/data.json'
        // }
        sync: {
            url: 'https://172.31.226.249:5000/post/info',
            // specify Content-Type for requests
            headers: {
                'Content-Type': 'application/json'
            },
        },
    },
    // This config enables response validation and dumping of found errors to the browser console.
    // It's meant to be used as a development stage helper only so please set it to false for production systems.
    validateResponse: true,
},


// eventStyle: 'colored',
// eventColor: null,
columns: [
    {
        type: 'tree',
        text: 'Name',
        width: 200,
        field: 'name'
    },
    {
        type: "aggregate",
        text: 'Uren',
        field: 'hours',
        width: 140,
        renderer: (data, x, y) => {
            if (data.record.events.length > 0) {
                let tot = 0

                for (let e of data.record.events) {
                    const a = moment(e.data.startDate)
                    const b = moment(e.data.endDate)


                    tot += b.diff(a, "hours", true)
                }

                return data.record.data.hours - tot
            }
            if (data.record.children?.length > 0) {
                return null
            }

            return data.record.data.hours
        },
    }
],
filterBarFeature: true,
stripeFeature: true,
timeRangesFeature: true,
treeFeature: true,

barMargin: 5,
rowHeight: 30,

startDate: new Date(2017, 1, 7, 8),
endDate: new Date(2017, 1, 7, 18),
viewPreset: 'hourAndDay',


features: {
    eventEdit: {
        // Uncomment to make event editor readonly from the start
        // readOnly : true,
        // Add items to the event editor
        items: {
            // resourceField : resourceComboConfig,

            // Using this ref hooks dynamic toggling of fields per eventType up
            eventTypeField: {
                type: 'combo',
                name: 'phase',
                label: 'Fase',
                // Provided items start at 100, and go up in 100s, so insert after first one
                weight: 110,
                items: ['tekenwerk', "ibs"]
            },
            eventEmployeeField: {
                type: 'combo',
                label: 'Werknemer',
                name: 'employeeID',
                weight: 130,
                items: ["Joris", "Johan"]

            },
            linkField: {
                type: 'displayfield',
                label: 'Link',
                name: 'id',
                weight: 600,
            }
        }
    }
},
};

The only thing we find in the request is this: b''


Post by alex.l »

Hi omerkati,

If you provide an URL for load, the load request will be passed. It will be GET request by default, but you can change it to POST if you need.

     crudManager: {
        autoSync: true,
        autoLoad: true,
        transport: {
            load: {
                url: 'https://172.31.226.249:5000/post/info',
                method : 'POST'
            },
            sync: {
                url: 'https://172.31.226.249:5000/post/info'
            },
        },
        validateResponse: true,
    },

But actually, what is the question?

All the best,
Alex


Post by omerkati »

The problem is we do not get any data send to the backend. How can we fix this? Does it need to load from the backend first? The only thing that sync request is doing is sending OPTIONS request to our backend


Post by alex.l »

Did you specify URL for load request? Please check Network tab in DevTools, do you see the request?

All the best,
Alex


Post by omerkati »

Is there a guide for how the backend needs to respond? Or work in general

Last edited by omerkati on Tue Jan 25, 2022 5:42 pm, edited 1 time in total.

Post by alex.l »

I cannot run your application because of redirecting and requesting for authentication.

But I checked the code. Your crudManager configuration looks valid.

Is there a guide for how the backend needs to respond?

Yes, there is an article about load data format here: https://bryntum.com/docs/scheduler/guide/Scheduler/data/crud_manager#loading-data
about saving data here
https://bryntum.com/docs/scheduler/guide/Scheduler/data/crud_manager#saving-data

All the best,
Alex


Post by omerkati »

Hi could you explain what the preflight request expects? We keep getting this error:

Access to fetch at 'https://172.31.226.249:5000/post/info?data=%7B%22type%22%3A%22load%22%2C%22requestId%22%3A16431262798310%2C%22stores%22%3A%5B%22events%22%2C%22resources%22%2C%22assignments%22%2C%22dependencies%22%5D%7D' from origin 'https://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.

When I use axios there is no problem and here is the response:

{
    "data": {
        "success": true,
        "requestId": 16431260795250,
        "resources": {
            "rows": [
                {
                    "id": 0,
                    "name": "Niels",
                    "hours": null,
                    "expanded": true
                },
                {
                    "id": 1,
                    "name": "Project",
                    "hours": null,
                    "expanded": true,
                    "parentId": 0
                },
                {
                    "id": 2,
                    "name": "RK1",
                    "hours": 40,
                    "parentId": 1
                },
                {
                    "id": 3,
                    "name": "ZK2",
                    "hours": 20,
                    "parentId": 1
                },
                {
                    "id": 4,
                    "name": "RK3",
                    "hours": 30,
                    "parentId": 1
                },
                {
                    "id": 5,
                    "name": "RK4",
                    "hours": 10,
                    "parentId": 1
                }
            ]
        },
        "events": {
            "rows": [
                {
                    "id": 0,
                    "employeeID": "Joris",
                    "projectID": 2,
                    "eventId": "0000000",
                    "name": "test",
                    "phase": "tekenwerk",
                    "startDate": "2017-02-07 11:00",
                    "endDate": "2017-02-07 14:00",
                    "eventColor": "red"
                }
            ]
        }
    },
    "status": 200,
    "statusText": "OK",
    "headers": {
        "content-length": "1436",
        "content-type": "application/json"
    },
    "config": {
        "transitional": {
            "silentJSONParsing": true,
            "forcedJSONParsing": true,
            "clarifyTimeoutError": false
        },
        "transformRequest": [
            null
        ],
        "transformResponse": [
            null
        ],
        "timeout": 0,
        "xsrfCookieName": "XSRF-TOKEN",
        "xsrfHeaderName": "X-XSRF-TOKEN",
        "maxContentLength": -1,
        "maxBodyLength": -1,
        "headers": {
            "Accept": "application/json, text/plain, */*"
        },
        "method": "get",
        "url": "https://172.31.226.249:5000/post/info?data=%7B%22type%22%3A%22load%22%2C%22requestId%22%3A16431260795250%2C%22stores%22%3A%5B%22events%22%2C%22resources%22%2C%22assignments%22%2C%22dependencies%22%5D%7D"
    },
    "request": {}
}

Here is the crudmanager:

    crudManager: {
        // autoSync: true,
        autoLoad: true,
        transport: {
            load: {
                url: 'https://172.31.226.249:5000/post/info',
                method : 'GET',
                headers:{
                    'Content-Type': 'application/json'
                }
            },
            // sync: {
            //     url: 'https://172.31.226.249:8081/events',
            //     // specify Content-Type for requests
            //     headers: {
            //         'Content-Type': 'application/json',
            //         authorization: "Bearer " + getCookie("ycon_auth0_token")
            //     },
            // },
        },
        // This config enables response validation and dumping of found errors to the browser console.
        // It's meant to be used as a development stage helper only so please set it to false for production systems.
        validateResponse: true,
    }
    

Sometimes it sends a options request before sending the get request. Do I need to add something to the load function?


Post by alex.l »

CORS policy is a browser-level security policy https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

I guess you can add headers to allow that if you need or set your web browser.

https://web.dev/i18n/en/cross-origin-resource-sharing/

All the best,
Alex


Post Reply