<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/css" href="https://www.aaron-gustafson.com/c/feed.min.css" ?><feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:amg="https://www.aaron-gustafson.com.com/amg-dtd/"><title>Aaron Gustafson: Content tagged API</title><subtitle>The latest 20 posts and links tagged API.</subtitle><id>https://www.aaron-gustafson.com</id><link href="https://www.aaron-gustafson.com/feeds/api.xml" rel="self"/><link href="https://www.aaron-gustafson.com"/><author><name>Aaron Gustafson</name><uri>https://www.aaron-gustafson.com</uri></author><updated>2025-12-16T19:46:29Z</updated><entry><id>https://www.aaron-gustafson.com/notebook/dynamic-datalist-autocomplete-from-an-api/</id><title type="html"><![CDATA[✍🏻 Dynamic Datalist: Autocomplete from an API]]></title><link href="https://www.aaron-gustafson.com/notebook/dynamic-datalist-autocomplete-from-an-api/" rel="alternate" type="text/html" /><published>2025-12-16T19:46:29Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>HTML’s <code>datalist</code> element provides native autocomplete functionality, but it’s entirely static—you have to know all the options up front. The <code>dynamic-datalist</code> web component solves this by fetching suggestions from an API endpoint as users type, giving you the benefits of native autocomplete with the flexibility of dynamic data.</p><p>This component is a modern replacement for <a href="https://github.com/easy-designs/jquery.easy-predictive-typing.js">my old jQuery predictive typing plugin</a>. I’ve reimagined it as a standards-based web component.</p><h2 id="basic-usage" tabindex="-1"><a class="header-anchor" href="#basic-usage" aria-hidden="true">#</a> Basic usage</h2><p>To use the component, wrap it around your <code>input</code> field and specify an endpoint:</p><pre class="language-html" tabindex="0"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dynamic-datalist</span><span class="token attr-name">endpoint</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>/api/search<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>search<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>Search<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span><span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>text<span class="token punctuation">”</span></span><span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>search<span class="token punctuation">”</span></span><span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>search<span class="token punctuation">”</span></span><span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>Type to search…<span class="token punctuation">”</span></span><span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dynamic-datalist</span><span class="token punctuation">&gt;</span></span></code></pre><p>As users type, the component makes GET requests to that endpoint, passing in the typed value as the “query” parameter (e.g., <code>/api/search?query=WHAT_THE_USER_TYPED</code>). The response from the endpoint is used to populates a dynamic <code>datalist</code> element with the results.</p><p>The structure of the response should be JSON with an <code>options</code> array of string values:</p><pre class="language-json" tabindex="0"><code class="language-json"><span class="token punctuation">{</span><span class="token property">“options”</span><span class="token operator">:</span><span class="token punctuation">[</span><span class="token string">“option 1”</span><span class="token punctuation">,</span><span class="token string">“option 2”</span><span class="token punctuation">,</span><span class="token string">“option 3”</span><span class="token punctuation">]</span><span class="token punctuation">}</span></code></pre><h2 id="how-it-works" tabindex="-1"><a class="header-anchor" href="#how-it-works" aria-hidden="true">#</a> How it works</h2><p>Under the hood, the component:</p><ol><li>Adopts (or creates) a <code>datalist</code> element for your <code>input</code>,</li><li>Listens for “input” events,</li><li>Debounces requests (waiting at least 250ms) to avoid overwhelming your API,</li><li>Sends requests to your endpoint with the current value of the <code>input</code>,</li><li>Reads back the JSON response,</li><li>Updates the <code>datalist</code><code>option</code> elements, and</li><li>Dispatches the update event.</li></ol><p>All of this happens transparently—users just see autocomplete suggestions appearing as they type.</p><h2 id="need-post%3F" tabindex="-1"><a class="header-anchor" href="#need-post%3F" aria-hidden="true">#</a> Need POST?</h2><p>You can change the submission method via the <code>method</code> attribute:</p><pre class="language-html" tabindex="0"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dynamic-datalist</span><span class="token attr-name">endpoint</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>/api/lookup<span class="token punctuation">”</span></span><span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>post<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>lookup<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>Lookup<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span><span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>text<span class="token punctuation">”</span></span><span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>lookup<span class="token punctuation">”</span></span><span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>lookup<span class="token punctuation">”</span></span><span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dynamic-datalist</span><span class="token punctuation">&gt;</span></span></code></pre><p>This sends a POST request with a JSON body: <code>{ &quot;query&quot;: &quot;…&quot; }</code>. Currently GET and POST are supported, but I could add more if folks want them.</p><h2 id="custom-variable-names" tabindex="-1"><a class="header-anchor" href="#custom-variable-names" aria-hidden="true">#</a> Custom variable names</h2><p>As I mentioned, the component uses “query” as the parameter name by default, but you can easily change it via the <code>key</code> attribute:</p><pre class="language-html" tabindex="0"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dynamic-datalist</span><span class="token attr-name">endpoint</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>/api/terms<span class="token punctuation">”</span></span><span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>term<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>search<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>Term search<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span><span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>text<span class="token punctuation">”</span></span><span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>search<span class="token punctuation">”</span></span><span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>term<span class="token punctuation">”</span></span><span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dynamic-datalist</span><span class="token punctuation">&gt;</span></span></code></pre><p>This sends the GET request <code>/api/terms?term=…</code>.</p><h2 id="working-with-existing-datalists" tabindex="-1"><a class="header-anchor" href="#working-with-existing-datalists" aria-hidden="true">#</a> Working with existing datalists</h2><p>If your <code>input</code> already has a <code>datalist</code> defined, the component will inherit it and replace the existing options with the fetched results, which makes for a nice progressive enhancement:</p><pre class="language-html" tabindex="0"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dynamic-datalist</span><span class="token attr-name">endpoint</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>/api/cities<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>city<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>City<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span><span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>text<span class="token punctuation">”</span></span><span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>city<span class="token punctuation">”</span></span><span class="token attr-name">list</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>cities-list<span class="token punctuation">”</span></span><span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>Type a city…<span class="token punctuation">”</span></span><span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>datalist</span><span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>cities-list<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>option</span><span class="token punctuation">&gt;</span></span>New York<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>option</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>option</span><span class="token punctuation">&gt;</span></span>Los Angeles<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>option</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>option</span><span class="token punctuation">&gt;</span></span>Chicago<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>option</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>datalist</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dynamic-datalist</span><span class="token punctuation">&gt;</span></span></code></pre><p>Users see the pre-populated cities immediately, and as they type, API results supplement the list. If JavaScript fails or the web component doesn’t load, users still get the static options. Nothing breaks.</p><h2 id="event-handling" tabindex="-1"><a class="header-anchor" href="#event-handling" aria-hidden="true">#</a> Event handling</h2><p>If you want to tap into the component’s event system, it fires three custom events:</p><ul><li><code>dynamic-datalist:ready</code> - Fired when the component initializes</li><li><code>dynamic-datalist:update</code> - Fired when the <code>datalist</code> is updated with new options</li><li><code>dynamic-datalist:error</code> - Fired when an error occurs fetching data</li></ul><pre class="language-javascript" tabindex="0"><code class="language-javascript"><span class="token keyword">const</span> element <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">“dynamic-datalist”</span><span class="token punctuation">)</span><span class="token punctuation">;</span>element<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">“dynamic-datalist:ready”</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">“Component ready:”</span><span class="token punctuation">,</span> e<span class="token punctuation">.</span>detail<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>element<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">“dynamic-datalist:update”</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">“Options updated:”</span><span class="token punctuation">,</span> e<span class="token punctuation">.</span>detail<span class="token punctuation">.</span>options<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>element<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">“dynamic-datalist:error”</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">“Error:”</span><span class="token punctuation">,</span> e<span class="token punctuation">.</span>detail<span class="token punctuation">.</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>Each event provides helpful <code>detail</code> objects with references to the <code>input</code>, <code>datalist</code>, and other relevant data.</p><h2 id="demo" tabindex="-1"><a class="header-anchor" href="#demo" aria-hidden="true">#</a> Demo</h2><p>Check out <a href="https://aarongustafson.github.io/dynamic-datalist/demo/">the demo</a> for live examples (there are also <a href="https://aarongustafson.github.io/dynamic-datalist/demo/unpkg.html">unpkg</a> and <a href="https://aarongustafson.github.io/dynamic-datalist/demo/esm.html">ESM</a> builds if you want to test CDN delivery):</p><figure id="fig-2025-12-06-03" class="media-container"><fullscreen-control class="talk__slides__embed video-embed__video"><iframe src="https://aarongustafson.github.io/dynamic-datalist/demo/" class="talk__slides__embed video-embed__video" frameborder="0"></iframe></fullscreen-control></figure><h2 id="grab-it" tabindex="-1"><a class="header-anchor" href="#grab-it" aria-hidden="true">#</a> Grab it</h2><p>The project is available on <a href="https://github.com/aarongustafson/dynamic-datalist">GitHub</a>. You can also install via npm:</p><pre class="language-bash" tabindex="0"><code class="language-bash"><span class="token function">npm</span><span class="token function">install</span> @aarongustafson/dynamic-datalist</code></pre><p>If you go that route, there are a few ways to register the element depending on your build setup:</p><h3 id="option-1%3A-define-it-yourself" tabindex="-1"><a class="header-anchor" href="#option-1%3A-define-it-yourself" aria-hidden="true">#</a> Option 1: Define it yourself</h3><pre class="language-javascript" tabindex="0"><code class="language-javascript"><span class="token keyword">import</span><span class="token punctuation">{</span> DynamicDatalistElement <span class="token punctuation">}</span><span class="token keyword">from</span><span class="token string">“@aarongustafson/dynamic-datalist”</span><span class="token punctuation">;</span>customElements<span class="token punctuation">.</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string">“dynamic-datalist”</span><span class="token punctuation">,</span> DynamicDatalistElement<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h3 id="option-2%3A-let-the-helper-guard-registration" tabindex="-1"><a class="header-anchor" href="#option-2%3A-let-the-helper-guard-registration" aria-hidden="true">#</a> Option 2: Let the helper guard registration</h3><pre class="language-javascript" tabindex="0"><code class="language-javascript"><span class="token keyword">import</span><span class="token string">“@aarongustafson/dynamic-datalist/define.js”</span><span class="token punctuation">;</span><span class="token comment">// or, when you need to wait:</span><span class="token keyword">import</span><span class="token punctuation">{</span> defineDynamicDatalist <span class="token punctuation">}</span><span class="token keyword">from</span><span class="token string">“@aarongustafson/dynamic-datalist/define.js”</span><span class="token punctuation">;</span><span class="token function">defineDynamicDatalist</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h3 id="option-3%3A-drop-the-helper-in-via-a-%3Cscript%3E-tag" tabindex="-1"><a class="header-anchor" href="#option-3%3A-drop-the-helper-in-via-a-%3Cscript%3E-tag" aria-hidden="true">#</a> Option 3: Drop the helper in via a <code>&lt;script&gt;</code> tag</h3><pre class="language-html" tabindex="0"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>./node_modules/@aarongustafson/dynamic-datalist/define.js<span class="token punctuation">”</span></span><span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>module<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span></code></pre><p>Regardless of how you register it, there are no framework dependencies—just clean autocomplete powered by your API. As I mentioned, it’s also available via CDNs, such as unpkg too, if you’d prefer to go that route.</p>]]></content><amg:twitter><![CDATA[Want API-driven autocomplete suggestions in your forms? Here’s a web component that makes it happen.]]></amg:twitter><amg:summary><![CDATA[The <code>datalist</code> element is great for autocomplete, but it’s static. The <code>dynamic-datalist</code> web component brings dynamic, API-driven suggestions to your text fields as users type.]]></amg:summary><summary type="html"><![CDATA[<p>The <code>datalist</code> element is great for autocomplete, but it’s static. The <code>dynamic-datalist</code> web component brings dynamic, API-driven suggestions to your text fields as users type.</p>]]></summary><category term="forms" /><category term="HTML" /><category term="JavaScript" /><category term="progressive enhancement" /><category term="web components" /><category term="web forms" /><category term="API" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/tipr-now-with-added-txt/</id><title type="html"><![CDATA[✍🏻 Tipr, now with added txt]]></title><link href="https://www.aaron-gustafson.com/notebook/tipr-now-with-added-txt/" rel="alternate" type="text/html" /><published>2007-07-29T18:50:19Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>So, as it turns out, <a href="http://tipr.mobi">this little app I built for myself</a> is actually useful to other folks.</p><p>Over the 3 weeks since it launched, I’ve been keeping an eye on the traffic patterns, reviews, and mentions of Tipr across the intarwebs, but I’ve also been busily adding some new features, which brings me to this post. I knew people with iPhones and other capable mobile browsers were quite happy with Tipr, but folks without a mobile browser or with a sucky one were not, in my opinion, getting as much out of Tipr as I’d like them to. I wanted to correct that.</p><p>My first thought was to create an SMS service for Tipr, but there’s no way I can afford to rig up a server capable of receiving and replying to SMS messages and I certainly could not afford to pay the $1000-2000/month for an SMS short code (after all, I’m not making any money on this thing). Then the answer dawned on me: <a href="http://twitter.com">Twitter</a>.</p><p><img alt="" class="alt-feature" src="http://farm2.static.flickr.com/1228/942768366_aae7fe823b_o.png"/></p><p>Since Twitter offers an SMS interface (40404 once you register your mobile), I could simply piggy back on their service to offer Tipr via SMS. All I had to do was build a TwitterBot capable of receiving and responding to messages. Lots of folks have built <abbr title="Instant Message">IM</abbr> bots in the past, but there weren’t that many TwitterBots and there was even less information about building one. Even with the odds stacked against me, however, after about an hour of reading <a href="http://groups.google.com/group/twitter-development-talk/web/api-documentation">the Twitter <abbr title="Application Programming Interface">API</abbr> documentation</a> and 6 hours of actual programming, I had built a working <abbr title="Hypertext PreProcessor">PHP</abbr>-based TwitterBot class.</p><p>The whole thing works using Twitter’s direct message functionality and runs several independent services to do things like reciprocate friendships, check the inbox, process responses, and send messages back. Unfortunately, the <abbr title="Application Programming Interface">API</abbr> was only able to get me so far, so I did have to resort to a little hackery to get some of it to work, but in the end, the Tipr TwitterBot, which sits on top of my generic TwitterBot class is pretty solid and quite responsive — even with the 70 <abbr title="Application Programming Interface">API</abbr> calls in 60 minutes limitation, most messages receive a response in approximately 45 seconds (depending on your network and whether Twitter is releasing a new feature and takes the service offline for a few minutes).</p><p>Overall, I’m pretty happy with the results and the early beta testers seem to be liking it as well. Hopefully some of you out there will find it as useful (if not more so) than the web interface. If you’re on Twitter, <a href="http://tipr.mobi/twitter.php">give it a shot</a> and let me know what you think.</p>]]></content><amg:summary><![CDATA[So, as it turns out, this little app I built for myself is actually useful to other folks.]]></amg:summary><summary type="html"><![CDATA[<p>So, as it turns out, this little app I built for myself is actually useful to other folks.</p>]]></summary><category term="mobile" /><category term="API" /><category term="JavaScript" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/got-ajax-skills-odeo-beckons/</id><title type="html"><![CDATA[✍🏻 Got AJAX Skills? Odeo beckons]]></title><link href="https://www.aaron-gustafson.com/notebook/got-ajax-skills-odeo-beckons/" rel="alternate" type="text/html" /><published>2006-01-09T15:21:02Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>The fine folks over at Odeo are looking for an “<a href="http://www.odeo.com/about/jobs#ajax"><abbr title="Asynchronus JavaScript and XML">AJAX</abbr> Engineer</a>” to round out their web dev team. If you live &amp; breathe JavaScript, CSS, XHTML and live in or around San Francisco, drop them a line (jobs [at] odeo [dot] com). Everyone I know that works there seems to love it, making me wish I lived a little closer to SF.</p>]]></content><amg:summary><![CDATA[The fine folks over at Odeo are looking for an “ AJAX Engineer ” to round out their web dev team. If you live &amp; breathe JavaScript, CSS , XHTML and live in or around San Francisco, drop them a line (jobs [at] odeo [dot] com). Everyone I…]]></amg:summary><summary type="html"><![CDATA[<p>The fine folks over at Odeo are looking for an “ AJAX Engineer ” to round out their web dev team. If you live &amp; breathe JavaScript, CSS , XHTML and live in or around San Francisco, drop them a line (jobs [at] odeo [dot] com). Everyone I…</p>]]></summary><category term="API" /><category term="JavaScript" /><category term="career" /></entry></feed>