I've been developing a music Service for Sonos and have everything up and running. The problem I have is Sonos only requests 99 items through it's getMetadata call, some of my libraries have 300+ tracks in, so I'd ideally like to list them all out.
I can't find anything in the Sonos api documentation about how to list 100 or more items but I'm assuming it is possible because their reference page for getScrollIndices (http://musicpartners.sonos.com/node/103) alludes to a library much larger than 100 tracks.
You can set the default number of items requested in a getMetadata call by setting the BrowseOptions.PageSize value to something more appropriate for your service in a presentationmap.xml file.
E.g.:
<?xml version="1.0" encoding="utf-8" ?>
<Presentation>
<!-- I chose 400 based on your 300+ value in the question. -->
<BrowseOptions PageSize="400" />
</Presentation>
You can find documentation at the link below. Scroll down to 'Browse Options':
http://musicpartners.sonos.com/node/222
And you can find documentation on how to configure Sonos to read your Presentation Map during local testing here:
http://musicpartners.sonos.com/node/134
In essence, you need to host the XML file on a server (often the same server that hosts your Sonos API code), and configure the URL in the customSD form that points directly to the presentationmap.xml file.
Note: Sonos caches the XML file for performance. When you change the file, you must increment the version in the customSD form so Sonos controllers force a reload. This is explained in the 'Version' entry in the documentation here:
http://musicpartners.sonos.com/node/134
Related
I have a SvelteKit Component that needs a corresponding +page.server.ts for cookie authenticated form actions. My goal is to have a Component with a corresponding delete button that will send an API request to my backend from within a form action inside a +page.server.ts endpoint.
My structure for some clarity:
- src/
- components/
- Component/
- +page.svelte
- +page.server.ts
- routes/
- route/
- +page.svelte
Component +page.svelte:
<div class="card">
<form method="POST">
<input type="hidden" value="{uuid}" name="uuid" />
<button class="btn-icon variant-filled-primary">
<span><Icon icon="material-symbols:delete-outline"></Icon></span>
</button>
</form>
</div>
Component +page.server.ts:
import type { Actions } from './$types';
export const actions = {
default: async ({ cookies, request }) => {
// Doing some http-only Cookie authenticated fetching and data processing here
}
} satisfies Actions;
The component is being rendered as perfectly fine as it did when I was still using just Component.svelte as my structure/nomenclature without a dedicated folder and +page.svelte.
The error I'm getting from within my browser after clicking the submit button in the component goes as follows:
405 POST method not allowed. No actions exist for this page
I figured this behaviour may appear since I don't have any form actions specified for my Routes +page.svelte but for my Components +page.svelte which, for whatever reason, won't be executed when clicking the form submit button.
Is my approach to this problem even possible of a solution or am I being forced right here to roll back and just use Route Form Actions from within every single route that utilizes my component? Doesn't seem like a very scalable option to me.
One thing to keep in mind with Sveltekit is that you get a lot of "magic" in the name of keeping things easy to use and on the happy path. The whole framework is designed around that premise and makes use of conventions to get it done.
Your src/routes directory is a convention that the whole router is built around, so anything that needs to execute routing behavior out of the box needs to be inside that directory. However, you still have a large amount of flexibility in how it all gets put together. In this case you have a couple of options.
Options 1: API Routes
As people have mentioned in the comments, you can use the routes directory to build out an API structure independent of any .svelte files that will render. A common structure would be something like this, which would create a standard endpoint route:
- src/
- routes/
- api/
- delete/
- +server.js
Inside the +server.js file you can build out standard handlers for GET, POST, etc. Then you can call the endpoint as a relative path from the root path, anywhere in the app and from any component using fetch, and you can also call it from other +page.js and +*.server.js files. In this case the route is reached with the path /api/delete.
Option 2: Co-locate components with routes
Another option if the component only relates to one route is to co-locate the component in the routes directory. If it doesn't have the + prefix it will be ignored by the router. This makes the following structure valid:
- src/
- routes/
- route/
- FormComponent.svelte
- +page.svelte
- +page.server.js
- utilities.js
In this case, both the FormComponent and the utilities files are ignored by the router, but both are still accessible from other files in the route. In cases where you need to decompose pieces of a page for reuse in that page, but those pieces only apply to the route in question, this can massively simplify your dependency map between files. Note that files placed in routes using this pattern can still be used elsewhere with standard relative path imports, but if you need to access them somewhere else they are probably better off living in the $lib directory.
A note about the official docs
I have found that the official docs are complete, but are also very succinct. There isn't a lot in the way of code examples, just enough to get you going. It's a great resource for reference but it can be challenging for discovery. Also an understanding of vanilla Svelte is assumed throughout, along with an understanding of HTTP conventions and web standards.
With that in mind, asking question here is encouraged, along with the official Svelte discord community which also covers Sveltekit. I've also found the Reddit community to be very helpful.
I have a panel used in multiple pages in an app we're developing. In this panel is a FileUploadField that uses AjaxFormSubmitBehavior (extended as FileUploadBehavior) on "change" to upload a file, which I then add to a list via ajax, update the view, clear the FileUploadField, and then allow them to select another file. And this is in fact exactly what happens in one of the pages using the panel...but not in another. In the non-working page, the first file selected is repeated over and over regardless of what file is picked after the first.
In the onSubmit of the behavior, we get the the FileUpload object which is supposed to be different between requests. I can see in the debugger that the FileUpload is the exact same object as the previous request, not merely carrying the same payload.
I'm scrutinizing the usage of the panel on the two pages and see no material differences. I can see the file control on the page DOES show the changed file name while I sit at my breakpoint on the server (so I suspect whatever is going wrong is on the java side). But I can't figure out why they behave differently or see where it's going wrong. The panels and pages are large and complex, so here's snippets of the relevant pieces.
FileUploadBehavior.onSubmit(AjaxRequestTarget) :
FileUploadField fileUploadField = (FileUploadField) fileUploadContainer.get("fileUploadField");
FileUpload fileUpload = fileUploadField.getFileUpload();
[...]
//clear file input after each request for next upload.
fileUploadField.clearInput();
target.add(fileUploadField);
I have a break right after this line and can see the first file gets repeated. The code that instantiates the field and behavior in the panel looks like:
FileUploadField fileUploadField = new FileUploadField("fileUploadField");
fileUploadField.add(new FileUploadBehavior("change", maxFileSize).setDefaultProcessing(false));
fileUploadContainer.add(fileUploadField);
The html tag:
<input wicket:id="fileUploadField" class="form-control" type="file" id="formFile" multiple>
I feel like the fact that it works in one page and not in another leads me to think the problem is outside the panel. The fact that the control in the browser shows the 2nd filename during test leads me to think it's on the java side. But nothing about the file event or definition happens outside the panel itself. The form elements are declared identically, and both have multipart enctypes when the pages render. Both successfully upload their first file. I'm kind of not even sure where to look for why wicket is re-using the FileUpload object in one page but not in another.
I should mention that we use Apache Wicket 6.26.
update: I looked into the source of FileUploadField, and it has an explicit check on whether FileUploads is null in it's internal property, and if so returns it without checking the actual request. I don't see any way to clear this value between requests. clearInput() doesn't affect it from what I see. I'm more confused by how this is working in one page than why it's not in the one where it doesn't now. I also don't know how to make the class 'reset' between requests.
Okay, figured this out. As martin-g pointed out, the fileUploads is set null in onDetach(), which I discovered about an hour after my update. The problem is that the onDetach() first tries to null out the model object. But that method was blowing up because there was no method 'fileUploadField' on the model attached to the form which was a compound property model. The page that worked does NOT use a compound property model for the form. For some reason, when this error occurred, it was being swallowed somewhere in the call stack and did not end up in my console log.
My solution was to provide a local model to the fileUploadField since that's not how I'm interacting with the control anyway (I'm using ajax and getting the FileUpload directly each time). That fixed it. It now works everywhere.
I am using Google Chromes Advanced REST Client to try some REST calls to SharePoint and Project Server.
I managed to read the data with a simple GET. I get an XML back that has all the properties for the given object. For instance if there's a Project object, this would have a Project Name property.
<entry xmlns....
....
<m:properties>
<d:ProjectName>Test Project </d:ProjectName>
... a lot more properties ...
</m:properties>
... *some other tags* ...
</entry>
I would very much like to update this Project Name, and in the SDK I read that the Project object supports the DELETE, MERGE, PUT methods. I've read that the MERGE one is the one which allows the user to only update selected properties without taking effect on others. The Advanced REST Client however does not have a MERGE, but it has a PATCH.
How should I construct the request, the headers and how should I specify the new name for the project?
I tried to write in the following in the Payload section of the request:
{"ProjectName"="New Name"}
It came back with a 403 (Forbidden) error.
I have an single page application created in MVVM and knockout,typescript technology.
I am using knockout templating for creating different views within a Page.
The application Page has a view which shows a list of tasks user can start,pause,resume tasks.accordingly status changes using knockout.The database is getting updated but the UI doesnt reflect changes.
This application works fine in chrome but in IE the page doesn't get refreshed.In IE when from settings i choose request for new version of stored pages everytime.It works fine in IE also.
can any one help me out with a solution for this problem
It seems that your problem with the non-refreshing UI is a json caching problem.
Try to disable jquery ajax caching
$.ajaxSetup({ cache: false });
globally or just temporarily for the request which causes the problem.
IE is caching JSON responses, you wil find your response as a .json file in the temporary internet files folder :)
More information can be read here
I want to use the #! token to make my GWT application crawlable, as described here:
http://code.google.com/web/ajaxcrawling/
There is a GWT sample app available online that uses this, for example:
http://gwt.google.com/samples/Showcase/Showcase.html#!CwRadioButton
Will serve the following static webpage to the googlebot:
http://gwt.google.com/samples/Showcase/Showcase.html?_escaped_fragment_=CwRadioButton
I want my GWT app to do something similar. In short, I'd like to serve a different flavor of the page whenever the _escaped_fragment_ parameter is found in the URL.
What should I modify in order for the server to serve something else (a static page, or a page dynamically generated through a headless browser like HTML Unit)? I'm guessing it could be the web.xml file, but I'm not sure.
(Note: I thought of checking the Showcase app provided with the GWT SDK, but unfortunately it doesn't seem to support serving static files on _escaped_fragment_ and it doesn't use the #! token..)
If you want to use web.xml, then I think it won't work with a servlet-mapping, because the url-patterns ignore the get parameters. (Not 100% sure, if there is another way to make this possible.)
You could of course map Showcase.html to a servlet, and in that servlet decide what to do, based on the get parameter "_escaped_fragment_". But it's a little bit expensive to call a Servlet just to serve a static page for the majority of the requests (not too bad, but still. You could set cache headers, if you're sure that it doesn't change).
Or you could have an Apache or something in front of your server - but I understand, I wouldn't like to have to do that either. Maybe your JavaEE server (which one are you using BTW?) provides some mechanism for URL filtering before the request gets passed on to the web container - I'd like to know that, too!
Found my answer! The Showcase sample supporting crawlable hyperlinks is in the following branch:
http://code.google.com/p/google-web-toolkit/source/browse/branches/crawlability/samples/showcase/?r=7726
It defines a filter in the web.xml to redirect URLs with the _escaped_fragment_ token to the output of HTML Unit.