Trouble switching to urql offlineExchange; runtime error: TypeError: Cannot read property 'length' of undefined - offline

I am attempting to switch to using the urql offlineExchange.
Getting the following error:
<!-- language: lang-none -->
TypeError: Cannot read property 'length' of undefined
ha
https://rdududevw10sdn.dsa.int:3443/static/js/0.chunk.js:23933:10
Module../src/index.js
E:/CCase/sdickerson_wfm14216_view/AnsosWeb/WSM/Application/app/src/index.js:33
30 | optimistic: {},
31 | });
32 |
> 33 | const client = createClient({
34 | url: WSM_URL,
35 | exchanges: [dedupExchange, cache, fetchExchange],
36 | })
I'm attempting to follow the Offline Support documentation (Offline Support.
index.js:
const WSM_URL = '/api/gql'
const introspectedSchema = {
__schema: {
queryType: {name: 'Query',},
mutationType: {name: 'Mutation',},
subscriptionType: {name: 'Subscription',},
},
}
const storage = makeDefaultStorage({
idbName: 'graphcache-v3', // The name of the IndexedDB database
maxAge: 7, // The maximum age of the persisted data in days
})
const cache = offlineExchange({
schema: introspectedSchema,
storage,
updates: {},
optimistic: {},
});
const client = createClient({
url: WSM_URL,
exchanges: [dedupExchange, cache, fetchExchange],
})

Related

Nuxt 3 set cookies on FE

I'm migrating a project to Nuxt 3 and I don't know how to convert a Nuxt 2 code using the new setup script
I have a login that if return a 200 response I would save 2 cookie but
$fetch(`${runtimeConfig.public.BASE_API_BROWSER_URL}/user/login`, {
method: 'POST',
body: {
email: email.value,
password: password.value,
}
})
.then((resp) => {
localStorage.setItem('Bearer', resp.access_token)
// Cookie.set('Bearer', resp.data.access_token, { expires: 7 })
isSubmitting.value = false
window.location.href = '/profile/'
})
I was using js-cookie but I was wondering if I could achieve the same without the need of a dependency, I know I can use vanilla js but I was wondering if use-cookie would work as well.
I've tried this useCookie('Bearer', resp.access_token, { maxAge: 60 * 60 * 24 * 7 }) but doesn't seems to work
Leveraging the built in useCookie would look like this to set a value:
// Login Script
const myCookieToken = useCookie('myCookieToken', { maxAge: 60 * 60 * 24 * 7 })
$fetch('...').then(response => {
myCookieToken.value = response.access_token
}
To retrieve the value later in another script or component:
const myCookieToken = useCookie('myCookieToken')
console.log(myCookieToken.value)
PS... You may want to use navigateTo('/profile') instead of window.location.href so you get the nice built in page transition.

Next js with django api rendering data

I am working on a front end of a project and I am stuck for a while.
I have created an api with django rest framework and I am trying to connect to a Nextjs front end. The data is to show on the front page that is why I call getInitialProps. Following is the code
import styles from '../styles/Home.module.css';
import axios from 'axios';
const Home = ({ listings, error }) => {
if (error) {
return <div>An error occured: {error.message}</div>;
}
return (
<ul>
{listings.map((listing) => (
<li key={listing.address}>{listing.title}</li>
))}
</ul>
);
};
Home.getInitialProps = async (ctx) => {
try {
const res = await axios.get('http://127.0.0.1:8000/api/listings/?page=4');
const rep = await res.data;
console.log(rep.results);
listings = rep.results;
return { listings };
} catch (error) {
return { error };
}
};
export default Home;
In the console log I get the data, which is in the bellow format:
[
{
index: 1734112,
user: 11233,
title: 'Classical style',
address: 'address 23, city , country',
bedrooms: '2',
bethrooms: '1',
price: '5803',
list_type: 'rent'
},
{
index: 1722303,
user: 32119,
title: 'Pangrati On the Lake',
address: 'address 28, city , country',
bedrooms: '1',
bethrooms: '1',
price: '4800',
list_type: 'rent'
}
]
But I get an error occured in the browser without specifying the error.
And in the console I get the bellow.
next-dev.js?3515:32 Warning: Did not expect server HTML to contain the text node "listings is not defined" in <div>.
at div
at Home (webpack-internal:///./pages/index.js:50:26)
at MyApp (webpack-internal:///./pages/_app.js:38:27)
at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/client.js:8:20584)
at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/client.js:8:23125)
at Container (webpack-internal:///./node_modules/next/dist/client/index.js:359:9)
at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:793:26)
at Root (webpack-internal:///./node_modules/next/dist/client/index.js:915:27)
I am not sure what the issue is so any help much appreciated. Thank you!
You are assigning value to some variable listings = rep.results;, but this variable was not declared, you can't do that in strict mode (which I believe is default in that case)
So just declare it as const and the error should go away:
const listings = rep.results

Jest .toBeCalledWith objectContaining not matching expect on received

I am trying to partially match the object which are being passed to TitleRepo.find. I am not able to understand what wrong I am doing.
expect(jest.fn()).toBeCalledWith(...expected)
Expected: ObjectContaining {"filter": {"limit": Any<Number>}}
Received: {"filter": {"title_ids.xxx.deleted_at": null, "title_ids.xxx.deleted_at": null, "title_ids.xxx.id": {"$exists": true, "$ne": null}}, "limit": 10, "sort": {"created_at": -1}}
Number of calls: 1
31 | });
32 |
> 33 | expect(TitleRepo.find).toBeCalledWith(
| ^
34 | expect.objectContaining({"filter": {"limit": expect.any(Number)}}),
35 | );
36 | })
at Object.<anonymous> (tests/query/TitleQuery.test.js:33:32)
Related lines from test is.
TitleRepo.find = jest.fn();
it('should able to set platform correctly', async () => {
const titles = await TitleQuery.find({
platform: 'chandu'
});
expect(TitleRepo.find).toBeCalledWith(
expect.objectContaining({"filter": {"limit": expect.any(Number)}}),
);
})
limit property is on the same level as filter.
It should be:
expect(TitleRepo.find).toBeCalledWith(expect.objectContaining({ limit: expect.any(Number) })

Using expect.any() with supertest to check response body

I'm trying to use supertest to check res.body with Jest, but the following snippet will always fail
request(app)
.post('/auth/signup')
.send(validEmailSample)
.expect(200, {
success: true,
message: 'registration success',
token: expect.any(String),
user: expect.any(Object),
});
But when I rewrite the test to check the body in a callback as follows:
test('valid userData + valid email will result in registration sucess(200) with message object.', (done) => {
request(app)
.post('/auth/signup')
.send(validEmailSample)
.expect(200)
.end((err, res) => {
if (err) done(err);
expect(res.body.success).toEqual(true);
expect(res.body.message).toEqual('registration successful');
expect(res.body.token).toEqual(expect.any(String));
expect(res.body.user).toEqual(expect.any(Object));
expect.assertions(4);
done();
});
});
The test will pass.
I'm sure it has something to do with expect.any(). As Jest's documentation says that expect.any and expect.anything can only be used together with expect().toEqual, and expect().toHaveBeenCalledWith()
I'm wondering if there's any better way to do it, to use expect.any in supertest's expect api.
You can use expect.objectContaining(object).
matches any received object that recursively matches the expected properties. That is, the expected object is a subset of the received object. Therefore, it matches a received object which contains properties that are present in the expected object.
app.js:
const express = require("express");
const app = express();
app.post("/auth/signup", (req, res) => {
const data = {
success: true,
message: "registration success",
token: "123",
user: {},
};
res.json(data);
});
module.exports = app;
app.test.js:
const app = require('./app');
const request = require('supertest');
describe('47865190', () => {
it('should pass', (done) => {
expect.assertions(1);
request(app)
.post('/auth/signup')
.expect(200)
.end((err, res) => {
if (err) return done(err);
expect(res.body).toEqual(
expect.objectContaining({
success: true,
message: 'registration success',
token: expect.any(String),
user: expect.any(Object),
}),
);
done();
});
});
});
Integration test result with coverage report:
PASS src/stackoverflow/47865190/app.test.js (12.857s)
47865190
✓ should pass (48ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
app.js | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 14.319s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/47865190

2 dimensional table in Ember.js

We're evaluating Ember.js (against Angular) for a complex app by building a few "toy apps". One of them is to present data in a table.
I've been through countless SO postings, the Ember Website, and other sites but can't quite find the key to making it work. The closest examples were at xeqtit and this fiddle.
Quite stuck.
Any pointers to how to set this up? Been reading web postings for days just don't see the answer out there...
The Problem Statement
To simplify the problem: imagine a list of routers, each router can have a variable number of interfaces, those interfaces have an address, status, etc.
The final table would look like:
__________________________________________________
Machine | Interfaces
rt1.rp.ps.com | UP | UP | UP | NG | UP | UP | NG |
rt2.rp.ps.com | UP | UP | |
rt3.rp.ps.com | UP | UP | UP | |
rt4.rp.ps.com | UP | UP | UP | NG | UP | UP | NG |
rt5.rp.ps.com | UP | UP | UP | NG | |
--------------------------------------------------
Note the variable number of columns.
The Objects:
App.Machine = Ember.Object.extend(
{
nickname: '',
address: '',
ifaces: []
});
App.Interface = Ember.Object.extend(
{
num: '',
status: '',
address: ''
});
The Markup
<script type="text/x-handlebars" data-template-name="machinelist">
<p>List of Machines</p>
<table>
{{#each App.MachinelistController }}
<tr>
<td>{{nickname}}</td>
<td>{{address}}</td>
<td>
<table>
{{#each p in App.MachinelistController.getInterfaces}}
<tr><td>{{p}}</td></tr>
{{/each}}
</table>
</td>
</tr>
{{/each}}
</table>
</script>
The Controller
The Controller first reads a database to get a list of machines and their addresses. It then queries each machine to fetch the list of interfaces. [I've simplified the code to show the core of the issue ... excuse any typos]
App.MachinelistController = Ember.ArrayController.create(
{
content: [],
getInterfaces: function(x, y, z)
{
// This didn't work
return this.getPath('interfaces.status');
}.property('#each.read'),
polling: false,
machinePollTime: 5000,
detailPollTime: 3000,
The list of machines is retrieved from a database via PHP. It populates the 'content' of the Controller with Machine objects, but no details on the interfaces are filled in yet:
fetch: function()
{
console.log('machine fetch');
var self = this;
$.get("be/getDVStorList.php", function(data, textStatus)
{
self.set('content', []);
var statusReport = jQuery.parseJSON(data);
statusReport.machineList.forEach(function(v)
{
var machine = App.Machine.create(
{
nickname: v['machineName'],
address: v['machineIpAddr']
});
self.pushObject( machine );
})
});
if (self.polling)
setTimeout( function() { self.fetch(); }, self.machinePollTime);
return this;
},
In a separate polling loop (still in the ArrayController), each machine in the content list is polled to get the info about its interfaces:
fetchDetails: function ()
{
console.log("fetch details");
var self = this;
self.forEach(function(item, index, self)
{
console.log(item.get('address'));
var addr = item.get('address');
var base = "http://"+ addr;
var slug = "/cgi-bin/DvStorGetStatus.cgi?Recording=1&Playback=1&Structured=1";
$.ajax(
{
url: base+slug,
timeout: 10000,
cache: false,
success: buildMachineCallback(addr),
});
});
if (self.polling)
setTimeout( function () { self.fetchDetails(); }, self.detailPollTime);
return true;
function buildMachineCallback(addr)
{
return function(data, textStatus, jqXHR) { updateDetailsCallback(data, textStatus, jqXHR, addr); };
};
This function is called when the poll to each machine returns. It adds the 'interfaces' into the data structure:
// Update *data structure* based on return values in XML
function updateDetailsCallback(data, textStatus, jqXHR, addr)
{
// might be more than one with this address
var theMachines = self.filterProperty('address')
var interfaceList = $(data).find('Interface');
var interfaces = [];
$(playInterfaceerList).each(function()
{
var anInterface = App.Interface.create();
var num = $(this).find('InterfaceNum').text();
anInterface.set('num', num);
anInterface.set('status', $(this).find('InterfaceStatus').text());
interfaces[num-1] = anInterface;
})
// update all machines sharing this IP address
theMachines.forEach(function (m, idx, tm)
{
tm[idx].set('alias', $(data).find('Generic').find('Alias').text());
tm[idx].set('health', $(data).find('Generic').find('SystemHealth').text());
interfaces.forEach(function(p)
{
tm[idx].get('ifaces').pushObject( App.Interface.create(p) );
})
});
}
}
});
There are two solutions that should works.
Ember-table, an Ember plugin: http://addepar.github.io/#/ember-table/overview
jQuery-datatable, a jQuery plugin: https://datatables.net/
Using the jQuery plugin will be more complicated because it is not directly linked to the ember render process.