We've been using the /venues/suggestcompletion endpoint for a while for our autocompletion feature for a while now.
It started returning empty arrays for all our queries recently.
Here is a sample set of GET parameters:
{
limit = 20;
ll = "52.485799,13.437771";
query = ostba;
}
resulting in this URL:
https://api.foursquare.com/v2/venues/suggestcompletion?client_id=OUR_CLIENT_ID&client_secret=OUR_CLIENT_SECRET&v=20120801&query=ostba&ll=52.485799,13.437771
and corresponding output:
meta = {
code = 200;
};
response = {
minivenues = (
);
};
I know /venues/suggestcompletion is meant as experimental but I couldn't find a notice of an API change. This is breaking the venue search functionality for our app in production. We'd appreciate any pointers.
Thanks a lot…
This was a temporary bug that was introduced yesterday. We believe we've fixed the problem -- sorry for that!
Related
I am implementing azure search in my application to provide autosuggestion feature like google, big, and amazon. I have implemented the same available github code using below URL.All is working fine but getting result in more than 1.5 second for each term of sentence.
https://github.com/Azure-Samples/search-dotnet-getting-started/tree/master/DotNetHowToAutocomplete
Currently I am using two indexes for searching and created in basic tier. Below is code
public ActionResult Suggest(bool highlights, bool fuzzy, string term)
{
InitSearch();
// Call suggest API and return results
SuggestParameters sp = new SuggestParameters()
{
UseFuzzyMatching = fuzzy,
Top = 5,
Filter="name eq 'testid'",
OrderBy=new List<string>() { "Date desc"}
};
if (highlights)
{
sp.HighlightPreTag = "<b>";
sp.HighlightPostTag = "</b>";
}
DocumentSuggestResult suggestResult = _indexClient1.Documents.Suggest(term, "index1",sp);
if (suggestResult.Results.Count<5)
{
SuggestParameters sp2 = new SuggestParameters()
{
UseFuzzyMatching = fuzzy,
Top = 5- suggestResult.Results.Count,
Filter = "Product eq 'PAAS'",
OrderBy = new List<string>() { "Count desc" }
};
if (highlights)
{
sp2.HighlightPreTag = "<b>";
sp2.HighlightPostTag = "</b>";
}
DocumentSuggestResult suggestResult2= _indexClient2.Documents.Suggest(term, "index2", sp2);
suggestResult.Results = suggestResult.Results.Union(suggestResult2.Results).Distinct().ToList();
// final = suggestResult.Results.GroupBy(s => s.Text, StringComparer.CurrentCultureIgnoreCase).ToList();
}
// Convert the suggest query results to a list that can be displayed in the client.
List<string> suggestions = suggestResult.Results.Select(x => x.Text).Distinct().ToList();
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = suggestions
};
}
To test it- when I am typing any word it's taking too much time in populating results around 1.5 to 1.8 seconds, it's working like other web app searchbox.
Timing I am checking using inspect element of chrome browser. Attaching sreenshot.see screenshot
Please suggest.
I answered a similar question on another post: Why is Azure Search taking 1400 miliiseconds to return query results for simple query
The main thing is, you shouldn't be using the Chrome timer to measure the performance of azure search. Use the "elapsed-time" field of the HTTP response you receive (take an average over multiple call), since it accurately tells you how much time was spent getting your results from azure search. The chrome timer can be affected by your network/machine configuration. If that doesn't help, you can follow the other tips I suggested in the post I linked above.
I'm using loopback 3.
I have this lines of codes in my model's js (survey.js):
let enabledRemoteMethods = []
Survey.sharedClass.methods().forEach(function(method) {
console.log(method.name, method.isStatic)
let matchingEnabledRemoteMethod = _.find(enabledRemoteMethods, {name: method.name});
if (!matchingEnabledRemoteMethod) {
Survey.disableRemoteMethodByName(method.name, method.isStatic);
}
});
It works.... almost. I could still see in the explorer the REST endpoint for "PATCH /surveys/{id}". My expectation is: there shouldn't be any REST endpoints listed in the explorer.
Then I examined the URL corresponding to that operation, it is:
http://localhost:3000/explorer/#!/Survey/Survey_prototype_patchAttributes
Which, according to the documentation, means that patchAttributes is a static method.
Then I cross checked with the output in the console... there it says: pathAttributes is not static.
Incosistency!
I even have tried adding this line:
Survey.disableRemoteMethodByName("patchAttributes", true);
Also
Survey.disableRemoteMethodByName("patchAttributes", false);
No luck.
Can someone confirm if it's a bug in loopback 3 (I don't know about loopback 2, haven't checked)? If it's a bug I wouldn't have to spend time on it and just wait until it gets fixed. But if it's not a bug, can someone point out what's missing in my code?
Thanks!
UPDATE: figured out how
With this line I'm able to get rid of it:
Survey.disableRemoteMethodByName("prototype.patchAttributes", true);
The second parameter doesn't seem to matter (you can put false as well). Not sure why though (I suppose it should've accepted true only).
This is my current solution:
let disabledPrototypesRemoteMethods = ['patchAttributes']
let enabledRemoteMethods = [
"create", "findById", "replaceById", "deleteById",
"replaceOrCreateQuestion"
]
Survey.sharedClass.methods().forEach(function(method) {
if (enabledRemoteMethods.indexOf(method.name) == -1) {
Survey.disableRemoteMethodByName(method.name);
}
if (disabledPrototypesRemoteMethods.indexOf(method.name) > -1) {
Survey.disableRemoteMethodByName("prototype." + method.name);
}
});
Still, one small detail: this thing still shows up (I suppose it provides the POST alternative for the normal PUT for the replaceById operation..., but I don't want it; I want to force user of my API to go with the PUT only):
http://localhost:3000/explorer/#!/Survey/Survey_replaceById_post_surveys_id_replace
I tried adding this line:
Survey.disableRemoteMethodByName("replaceById_post_surveys_id_replace");
No luck.
Anyway... hope this useful for others; loopback doc is kind of sketchy.
You can get the prototype methods as well by looking at the stringName property. That way you can include the prototypes in your list.
The stringName includes the sharedClass name in the value, so you will need to parse that out.
module.exports = BusinessProfileContacted => {
const enabledRemoteMethods = ["create", "findById", "replaceById", "deleteById", "replaceOrCreateQuestion", "prototype.replaceAttributes"];
Survey.sharedClass.methods().forEach(method => {
const methodName = method.stringName.replace(/.*?(?=\.)/, '').substr(1);
if (enabledRemoteMethods.indexOf(methodName) === -1) {
Survey.disableRemoteMethodByName(methodName);
}
});
};
My app is in the app store and all worked well but now foursquare has changed something and I can't get any places.
I search places in area and use "intend" = "browse". I researched that if change "intend" to "checkin" it works well, but I need "browse".
Additionally if I choose "checkin" I need to add "ll" parameter that I sometimes don't have.
My request:
https://api.foursquare.com/v2/venues/search?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&intent=browse&query=subway&v=20140806&m=foursquare&ne=59.969420,30.265150&sw=59.871682,30.388964&limit=50&categoryId=4bf58dd8d48988d1c5941735&ll=59.920551,30.327057
Response:
{
meta = {
code = 200;
};
response = {
venues = ();
};
}
Sorry for this, i garbled ne and sw with nw and se.
Remember that ne - top right corner,
sw - bottom left.
I've been banging my head against the desk for a while -- and searched far and wide for an answer to my problem. I have an isComputed property in a KO viewmodel in which I'm trying to concatenate properties of a child collection. However, it stubbornly returns a boolean value... I know I must be missing something really simple!
I'm just looking for a pointer as to what I'm doing wrong here:
self.allWorkcenters = ko.isComputed(function() {
var centers = "";
ko.utils.arrayForEach(self.locationScans(), function(item) {
var wc = item.workCenter.code();
centers += "\r\n" + wc;
});
/*
expecting something like "vutek, vutek, packing, finishing"
*/
return centers;
});
The whole object and data are here: http://jsfiddle.net/austriacus/mGAcU/
UPDATE: I'm an idiot... I used isComputed instead of computed. DUH. Ok, it's working: http://jsfiddle.net/austriacus/mGAcU/16/
Got it working. Funny how this works sometimes. Updated original question with the working fiddle link
I've created a snippet that pulls data from a databse table and displays it in tabular format. The snippet takes an id as parameter, and this is added to the sql query.
My problem is that if I've got more than 1 snippet call (sometimes need the tabular data for different id's displayed on a page) on the same page, all table data is the same as the last database call that's been made by the last snippet.
What do I need to do to kinda not cache the snippet database calls and have them all display their own content?
I've tried setting the page to no cache-able. Also used the [! !] brackets for the snippet calls, and even used the function_exists() method, but none of them helped.
Please can someone help me?
thanks
Try this at the end of the snippet:
mysql_connect('host', 'user', 'pass');
mysql_select_db('db_name');
You need to specify the connection parameters ofcourse.
It would help to answer if you can post your snippet. I do this with multiple calls on the page without issue, so there is either something wrong inside the snippet, or you need to output to unique placeholder names.
You have encountered a glitch of ModX, and it took me a long time to solve. ModX does a lot of caching by using hashing and apparently, when multiple connections are made from within one page divided over multiple snippets, this erratic behaviour can be seen. This is most likely very unwanted behaviour, it can be solved easily but gives you terrible headache otherways.
One sympton is that $modx->getObject($classname, $id)returns null (often).
The solution is very simple:
either use a static class with a single db instance, or
use $modx->setPlaceholder($instance, $tag);, or a combination.
My solution has been:
class dt__xpdo {
private function __construct() {}
public function __destruct() {
$this->close();
}
static public function db($modx = null) {
if ($modx->getPlaceholder('dt_xpdo') == '') {
$dt_user = 'xxxxxxxxx';
$dt_pw = 'xxxxxxxxx';
$dt_host = 'localhost';
$dt_dbname = 'xxxxxxxxx';
$dt_port = '3306';
$dt_dsn = "mysql:host=$dt_host;dbname=$dt_dbname;port=$dt_port;charset=utf8";
$dt_xpdo = new xPDO($dt_dsn, $dt_user, $dt_pw);
$dt_xpdo->setPackage('mymodel', MODX_CORE_PATH.'components/mymodel/'.'model/', '');
//$modx->log(modX::LOG_LEVEL_DEBUG, 'mymodel.config.php');
//$modx->log(modX::LOG_LEVEL_DEBUG, 'Could not addPackage for mymodel!');
$modx->setPlaceholder('dt_xpdo', $dt_xpdo);
}
return $modx->getPlaceholder('dt_xpdo');
}
}
Now you can use in your code:
require_once 'above.php';
and use something like
$xpdo = dt__xpdo::db($modx);
and continue flawlessly!