Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(@aws-amplify/datastore): Support SSR #5450

Closed
wants to merge 21 commits into from

Conversation

ericclemmons
Copy link
Contributor

@ericclemmons ericclemmons commented Apr 17, 2020

What

Add Next.js support (#5435) for DataStore:

import { Amplify, DataStore } from 'aws-amplify';
import { useState, useEffect } from 'react';

import awsConfig from '../src/aws-exports';
import { Post } from '../src/models';

Amplify.configure(awsConfig);

type Props = {
	posts: Post[];
};

export default function Home(initialData: Props) {
	// @ts-ignore Property 'fromJSON' does not exist on type 'typeof Post'.ts(2339)
	const [posts, setPosts] = useState(Post.fromJSON(initialData.posts));

	useEffect(() => {
		const subscription = DataStore.observe<Post>(Post).subscribe(
			({ element, opType }) => {
				const opTypeUpdaters = {
					DELETE: (posts) => posts.filter((post) => post.id !== element.id),
					INSERT: (posts) => [element, ...posts],
					UPDATE: (posts) =>
						posts.map((post) => (post.id === element.id ? element : post)),
				};

				setPosts(opTypeUpdaters[opType]);
			}
		);

		return () => subscription.unsubscribe();
	}, []);

	return ...
}

export async function getServerSideProps(context) {
	const posts = await DataStore.query<Post>(Post);

	return {
		props: {
			posts: DataStore.toJSON(posts),
		},
	};
}

Why

https://www.pivotaltracker.com/n/projects/2174488

How


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@ericclemmons ericclemmons self-assigned this Apr 17, 2020
@lgtm-com
Copy link

lgtm-com bot commented Apr 17, 2020

This pull request introduces 4 alerts when merging 2ece0d7 into dee0607 - view on LGTM.com

new alerts:

  • 4 for Syntax error

…datastore

# Conflicts:
#	packages/core/src/Util/Reachability.ts
#	packages/datastore/package.json
#	packages/datastore/src/datastore/datastore.ts
Argument of type '{ online: boolean; }' is not assignable to parameter of type 'Observable<NetworkStatus> | ObservableLike<NetworkStatus> | ArrayLike<NetworkStatus>'.
  Object literal may only specify known properties, and 'online' does not exist in type 'Observable<NetworkStatus> | ObservableLike<NetworkStatus> | ArrayLike<NetworkStatus>'.ts(2345)
Comment on lines +875 to +881
// In Node, we need to wait for queries to be synced to prevent returning empty arrays.
// In the Browser, we can begin returning data once subscriptions are in place.
const readyType = isNode
? ControlMessage.SYNC_ENGINE_SYNC_QUERIES_READY
: ControlMessage.SYNC_ENGINE_STORAGE_SUBSCRIBED;

if (type === readyType) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change fixes expected behavior in Node (particularly lambdas).

Notice here where I'm listening to Hub.listen('datastore') and finally logging out { posts }:

// 👇 Hub.listen('datastore', ...)
datastore {
  channel: 'datastore',
  payload: { event: 'storageSubscribed', data: undefined },
  source: '',
  patternInfo: []
}
datastore {
  channel: 'datastore',
  payload: { event: 'networkStatus', data: { active: true } },
  source: '',
  patternInfo: []
}
datastore {
  channel: 'datastore',
  payload: { event: 'outboxStatus', data: { isEmpty: true } },
  source: '',
  patternInfo: []
}
datastore {
  channel: 'datastore',
  payload: { event: 'subscriptionsEstablished', data: undefined },
  source: '',
  patternInfo: []
}
datastore {
  channel: 'datastore',
  payload: { event: 'syncQueriesStarted', data: { models: [Array] } },
  source: '',
  patternInfo: []
}
datastore {
  channel: 'datastore',
  payload: {
    event: 'modelSynced',
    data: {
      model: [Function],
      isFullSync: true,
      isDeltaSync: false,
      counts: [Object]
    }
  },
  source: '',
  patternInfo: []
}
datastore {
  channel: 'datastore',
  payload: {
    event: 'modelSynced',
    data: {
      model: [Function],
      isFullSync: true,
      isDeltaSync: false,
      counts: [Object]
    }
  },
  source: '',
  patternInfo: []
}
datastore {
  channel: 'datastore',
  payload: { event: 'syncQueriesReady', data: undefined },
  source: '',
  patternInfo: []
}
datastore {
  channel: 'datastore',
  payload: { event: 'ready', data: undefined },
  source: '',
  patternInfo: []
}
// 👇 { posts }
{
  posts: [
    Post {
      id: 'd4ad30d3-bb95-4cb2-9f55-b5917605e797',
      title: 'New Post (4/16/2020, 4:58:42 PM)',
      rating: 1,
      status: 'ACTIVE',
      _version: 2,
      _lastChangedAt: 1587081528053,
      _deleted: null
    },
    Post {
      id: '7b14789a-40a9-4b3a-8a23-849e3866f77a',
      title: 'New Post (4/17/2020, 3:17:13 PM)',
      rating: 4,
      status: 'INACTIVE',
      _version: 1,
      _lastChangedAt: 1587161833864,
      _deleted: null
    },
    Post {
      id: '2e5a6422-47e8-4693-b141-a126e8aaacfc',
      title: 'New Post (4/16/2020, 4:28:16 PM)',
      rating: 3,
      status: 'ACTIVE',
      _version: 2,
      _lastChangedAt: 1587081526956,
      _deleted: null
    },
    Post {
      id: 'f05918fc-2209-4013-a185-d6f9f8d9c468',
      title: 'New Post (4/20/2020, 2:04:21 PM)',
      rating: 2,
      status: 'INACTIVE',
      _version: 1,
      _lastChangedAt: 1587416662244,
      _deleted: null
    },
    Post {
      id: 'a94a6cc5-8a0b-441a-9da8-5dfc391df18d',
      title: 'New Post (4/16/2020, 4:58:43 PM)',
      rating: 3,
      status: 'INACTIVE',
      _version: 1,
      _lastChangedAt: 1587081523206,
      _deleted: null
    }
  ]
}
{
  posts: [
    Post {
      id: 'd4ad30d3-bb95-4cb2-9f55-b5917605e797',
      title: 'New Post (4/16/2020, 4:58:42 PM)',
      rating: 1,
      status: 'ACTIVE',
      _version: 2,
      _lastChangedAt: 1587081528053,
      _deleted: null
    },
    Post {
      id: '7b14789a-40a9-4b3a-8a23-849e3866f77a',
      title: 'New Post (4/17/2020, 3:17:13 PM)',
      rating: 4,
      status: 'INACTIVE',
      _version: 1,
      _lastChangedAt: 1587161833864,
      _deleted: null
    },
    Post {
      id: '2e5a6422-47e8-4693-b141-a126e8aaacfc',
      title: 'New Post (4/16/2020, 4:28:16 PM)',
      rating: 3,
      status: 'ACTIVE',
      _version: 2,
      _lastChangedAt: 1587081526956,
      _deleted: null
    },
    Post {
      id: 'f05918fc-2209-4013-a185-d6f9f8d9c468',
      title: 'New Post (4/20/2020, 2:04:21 PM)',
      rating: 2,
      status: 'INACTIVE',
      _version: 1,
      _lastChangedAt: 1587416662244,
      _deleted: null
    },
    Post {
      id: 'a94a6cc5-8a0b-441a-9da8-5dfc391df18d',
      title: 'New Post (4/16/2020, 4:58:43 PM)',
      rating: 3,
      status: 'INACTIVE',
      _version: 1,
      _lastChangedAt: 1587081523206,
      _deleted: null
    }
  ]
}

@ericclemmons ericclemmons marked this pull request as ready for review June 16, 2020 18:33
@ericclemmons
Copy link
Contributor Author

Fixed via #6146

@github-actions
Copy link

github-actions bot commented Sep 3, 2021

This pull request has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants